Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
CSE 501N
Fall ‘09
21: Introduction to Multithreading
19 November 2009
Nick Leidenfrost
Lecture Outline
Lab 8 questions?
Threads
Multithreading
Race conditions
2
Threads
A thread is a unit of execution in Java (and other
languages…)
Threads are executed independently of one
another
However,
they may share resources (Objects in your
program)
Threads execute simultaneously*
*The
Java Virtual Machine executes each thread in the
program for a short amount of time
This gives the impression of parallel execution
3
Threads
Programs we have written so far are
Single-Threaded
Java
creates the Main Thread for us when we
start our programs
Exception in thread "main" java.lang.NullPointerException
at OutOfBounds.doSomethingBad(OutOfBounds.java:25)
at OutOfBounds.<init>(OutOfBounds.java:21)
at OutOfBounds.main(OutOfBounds.java:10)
We will learn how to create additional
threads
“Multi-Threading”
/ Multi-Threaded Programs
4
Why Use Multiple Threads?
If we want to monitor something continuously
Incoming Data
More consistent user interaction
We can execute statements and accept rich user input (key
presses, mouse events) at the same time
Our program doesn’t appear to stall if we start a resource
intensive task
Writing a large amount of data to a stream
Simultaneous Execution
A large file to disk
A large amount of data sent across the net
When multiple processors exist (with proper JVM)
Simulated for single processor machines
Like all design decisions, the choice to use multiple
threads depends on your program goals
5
Creating Threads
Threads can be created in one of two
ways:
extending the java.lang.Thread class
By implementing the java.lang.Runnable
interface and passing our Runnable into a
Thread
By
6
Running a Thread
1.
Implement a class that implements the
Runnable interface
public interface Runnable {
void run();
}
7
Running a Thread
2.
Place the code for your task into the run
method of your class
public class MyRunnable implements Runnable {
public void run () {
// Task statements go here
. . .
}
}
8
Running a Thread
3.
Create an object of your subclass
Runnable r = new MyRunnable();
4.
Construct a Thread object from the
Runnable object.
Thread t = new Thread(r);
5.
Call the start method to start the thread.
t.start();
9
Starting a Thread
To start a Thread, we MUST call it’s
start() method
We
SHOULD NOT call run() directly
Also,
a thread is not started on creation
start will create a new thread of execution
and then call run() for us
// Inside MyThread
MyThread thread = new MyThread();
Thread.start();
public void run () {
while (!interrupted()) {
//... More statements ...
// ...
}
10
Starting a Thread
If we just call run() on the new Thread,
the current thread’s thread of execution
will execute the statements in run
MyThread thread = new MyThread();
Thread.run();
//... Not executed until ‘run’
// terminates ...
// Inside MyThread
public void run () {
while (!interrupted()) {
// ...
}
11
Example
• A program to print a time stamp and "Hello
World" once a second for ten seconds:
Thu
Thu
Thu
Thu
Thu
Thu
Thu
Thu
Thu
Thu
Dec
Dec
Dec
Dec
Dec
Dec
Dec
Dec
Dec
Dec
28
28
28
28
28
28
28
28
28
28
23:12:03
23:12:04
23:12:05
23:12:06
23:12:07
23:12:08
23:12:09
23:12:10
23:12:11
23:12:12
PST
PST
PST
PST
PST
PST
PST
PST
PST
PST
2004
2004
2004
2004
2004
2004
2004
2004
2004
2004
Hello,
Hello,
Hello,
Hello,
Hello,
Hello,
Hello,
Hello,
Hello,
Hello,
World!
World!
World!
World!
World!
World!
World!
World!
World!
World!
12
GreetingRunnable Outline
public class GreetingRunnable implements Runnable {
// Fields used by the task statements
private String greeting;
public GreetingRunnable(String aGreeting) {
greeting = aGreeting;
}
public void run() {
// Task statements go here
. . .
}
}
13
Thread Action for
GreetingRunnable
We want to:
Print
a time stamp
Print the greeting
Wait a second
We can get the date and time by
constructing a Date object
Date now = new Date();
14
Thread Action for
GreetingRunnable
To wait a second, use the sleep method of
the Thread class
sleep(milliseconds)
A sleeping thread can generate an
InterruptedException
Catch
the exception
Terminate the thread
15
Running Threads
sleep puts current thread to sleep for
given number of milliseconds
Thread.sleep(milliseconds)
When a thread is interrupted, most
common response is to terminate run
(We’ll
come back to interruptions in a bit)
16
Generic run Method
public void run() {
try {
// Task statements
}
catch (InterruptedException exception) {
}
// Clean up, if necessary
}
17
GreetingRunnable.java
// Code Example
20
Java Thread Scheduler
The thread scheduler runs each thread for
a short amount of time (a time slice)
Then the scheduler activates another
thread
There will always be slight variations in
running times especially when calling
operating system services (e.g. input and
output)
There is no guarantee about the order in
which threads are executed
24
Terminating Threads
A thread terminates when its run method
terminates
Do not terminate a thread using the
deprecated stop method
Instead, notify a thread that it should
terminate
t.interrupt();
interrupt does not cause the thread to
terminate–it sets a boolean field in the
Thread data structure
25
Terminating Threads
The run method should check occasionally whether it
has been interrupted
Use the interrupted method
An interrupted thread should release resources, clean
up, and exit
public void run() {
int i = 0;
while (i <= REPETITIONS && !Thread.interrupted()) {
// Do work
i++;
}
// Clean up
}
26
Terminating Threads
The sleep method throws an
InterruptedException when a
sleeping thread is interrupted
Catch
the exception
Terminate the thread
27
Terminating Threads
Java does not force a thread to terminate
when it is interrupted
It is entirely up to the thread what it does
when it is interrupted
Interrupting is a general mechanism for
getting the thread's attention
28
Swing Event Thread
When we open a window with Swing, Swing
provides us a Thread to handle events
You
have been writing multi-threaded programs
without knowing it!
// Code example
(Don’t worry about altering any of your Lab 8
code for thread interaction – we will do this in
later labs)
29
Sample Application
Create a BankAccount object
Create two threads:
t1
deposits $100 into the bank account for 10
iterations
t2 withdraws $100 from the bank account for
10 iterations
30
Sample Application
Monitor balance by modifying deposit
and withdraw to print messages:
public void deposit(double amount) {
System.out.print("Depositing " + amount);
double newBalance = balance + amount;
System.out.println(", new balance is " + newBalance);
balance = newBalance;
}
// Code Example
31
Sample Application
Normally, the program output looks
somewhat like this:
Depositing 100.0, new balance is 100.0
Withdrawing 100.0, new balance is 0.0
Depositing 100.0, new balance is 100.0
Depositing 100.0, new balance is 200.0
Withdrawing 100.0, new balance is 100.0
. . .
Withdrawing 100.0, new balance is 0.0
The result should be zero when the
program terminates, but sometimes it is
not…
32
Sample Application
Sometimes, you may notice messed-up
output, like this:
Depositing 100.0Withdrawing 100.0,
new balance is 100.0, new balance is -100.0
33
Race Conditions
When threads share common resources,
they can conflict with each other
Sample program: multiple threads
manipulate a common BankAccount
object
34
Race Conditions
Here is the run method of DepositRunnable:
public void run() {
try {
for (int i = 1; i <= count; i++) {
account.deposit(amount);
Thread.sleep(DELAY);
}
}
catch (InterruptedException exception) {
}
}
… the WithdrawRunnable class is similar
35
Scenario to explain Non-zero
Result: Race Condition
The first thread t1 executes the following
lines
System.out.print("Depositing " + amount);
double newBalance = balance + amount;
The balance field is still 0, and the
newBalance local variable is 100
t1 reaches the end of its time slice and
thread t2 gains control
36
Scenario to explain Non-zero
Result: Race Condition
t2 calls the withdraw method which withdraws
$100 from the balance, making it -100
t2 goes to sleep
T1 regains control and picks up where it left off –
it executes:
System.out.println(", new balance is " + newBalance);
balance = newBalance;
The balance is now 100 instead of 0 because
the deposit method has the OLD value for
balance
37
Corrupting the balance Field
Thread 1
System.out(“Depositing…”)
newBalance = balance + amount;
At this point, t1
reaches the end
of its time slice
Thread 2
newBalance is
100, balance is
still 0
System.out(“Withdrawing...”)
newBalance = balance - amount;
System.out(“The new balan...”)
balance = newBalance;
System.out(“The new balan...”)
balance = newBalance;
balance is set to
t2
goes to
balance
is set to
-100
sleep,
its
time
100, the value of
newBalance
slice
ends
38
Race Condition
Occurs if the effect of multiple threads on
shared data depends on the order in which
they are scheduled
It is possible for a thread to reach the end
of its time slice in the middle of a statement
It may evaluate the right-hand side of an
equation but not be able to store the result
until its next turn
39
Race Condition
public void deposit(double amount) {
balance = balance + amount;
System.out.print("Depositing " + amount + ",
new balance is " + balance);
}
Race condition can still occur:
balance = the right-hand-side value
40
Conclusion
Questions?
Soon: Thread-safety
Part 2 of Lab 8 is Online
Lab Now
41