Chapter a
Multithreading
Chapter Goals
- To understand how multiple threads can execute in parallel
- To learn how to implement threads
- To understand race conditions and deadlocks
- To be able to avoid corruption of shared objects by using synchronized methods
- To be able to use threads for programming animations
Threads
- A thread is a program unit that is executed independently of other parts
of the program
- The Java Virtual Machine executes each thread in the program for a short
amount of time
- This gives the impression of parallel execution
Steps to Running a Threads
- Implement a class that extends the Thread
class
- Place the code for your task into the run
method of your class
- Create an object of your subclass
- Call the start method of
your class to start the thread
- When a Thread object is started,
the code in its run method is executed in a new thread
GreetingThread Outline
A program to print a time stamp and "Hello World" once a second for ten seconds
public class GreetingThread extends Thread
{
public void run()
{
//thread action
. . .
}
//variables used by the thread action
. . .
}
Thread Action for GreetingThread
- Print a time stamp
- Print the greeting
- Wait a second
GreetingThread
- We can get the date and time by constructing a Date object
Date now = new Date();
- 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
GreetingThread run method
public run()
{
try
{
//thread action
)
catch (InterruptedException exception)
{
//cleanup, if necessary
}
}
File GreetingThread.java
To Start the Thread
File GreetingThreadTest.java
Thread Scheduler
- The thread scheduler runs each thread for a short amount of time called
a time slice
- Then the scheduler picks another thread from those that are runnable
- A thread is runnable if it is not asleep or blocked in some way
- There is no guarantee about the order in which threads are executed
Terminating Threads
- A thread terminates when its run method returns
- Do not terminate a thread using the deprecated stop method
- Instead, notify a thread that it should terminate
t.interrupt();
Terminating Threads
- A thread's run method should check occasionally whether it has been interrupted
- Use the isInterrupted method
- An interrupted thread should release resources, clean up, and exit
- The sleep method throws an InterruptedException when a sleeping thread is
interrupted
- Catch the exception
- Terminate the thread
Terminating a Thread
public void run(
{
try
{
for (int = 1;
i <= REPETITIONS && !isInterrupted();
i++)
{
//do the work
}
}
catch (InterruptedException exception)
{
}
//cleanup
}
Corrupting Data with Unsynchronized Threads
- When threads share a common object, they can conflict with each other.
- In this example, a DepositThread and a WithdrawThread
both manipulate a single BankAccount
run Method of DepositThread
public void run()
{
try
{
for (int i = 1; i <= REPETITIONS && !isInterrupted(); i++)
{
account.deposit(amount);
sleep(DELAY);
}
}
catch (InterruptedException exception)
{
}
}
Sample Application
- Create a BankAccount object
- Create a DepositThread t0 to deposit $100 into the account for
10 iterations
- Create a WithdrawThread t1 to withdraw $100 from the account for
10 iterations
- The result should be zero, but sometimes it is not
Scenario to Explain Non-zero Result
Scenario to Explain Non-zero Result
Race condition
- Occurs if the effect of multiple threads on shared data depends on the order
in which the threads 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.
Corrupting the Contents of the balance Field
File BankAccountThreadTest.java
File DepositThread.java
File WithdrawThread.java
File BankAccount.java
Solving the Race Condition Problem
- A thread must be able to lock an object temporarily
- When a thread has the object locked, no other thread can modify the state
of the object.
- In Java, use synchronized methods to do this
- Tag all methods that contain thread-sensitive code with the keyword synchronized
Synchronized Methods
public class BankAccount
{
public synchronized void deposit(double amount)
{
. . .
}
public synchronized void withdraw(double amount)
{
. . .
}
. . .
}
Synchronized Methods
- By declaring both the deposit and withdraw methods to
be synchronized
- Our program will run correctly
- Only one thread at a time can execute either method on a given object
- When a thread starts one of the methods, it is guaranteed to execute
the method to completion before another thread can execute a synchronized
method on the same object.
Synchronized Methods
- By executing a synchronized method:
- The thread acquires the object lock.
- No other thread can acquire the lock.
- No other thread can modify the state of the object until the first thread
is finished
Visualization of Synchronized Thread Behavior
- Imagine the object is a restroom that only one person can use at a time
- The threads are people
- If the restroom is empty, a person may enter
- If a second person finds the restroom locked, the second person must wait
until it is empty
- If multiple people want to gain access to the restroom , they all wait outside
- The people may not form an orderly queue;
- A randomly chosen person may gain access when the restroom becomes available
again
Deadlock
Deadlock
- The method can lead to deadlock
- The thread sleeps to wait for balance to grow, but it still has the lock
- No other thread can execute the synchronized deposit method
- If a thread tries to call deposit, it is blocked until the withdraw
method exits
- withdraw method can't exit until it has funds available
- DEADLOCK
Avoiding Deadlock
- The wait method temporarily releases the object lock and deactivates
the thread
- Restroom analogy
- Don't want the person in the restroom to go to sleep if there is no
toilet paper.
- Think of the person giving up and leaving
- This gives another person a chance to enter and refill the toilet paper
withdraw Method to Avoid Deadlock
public synchronized void withdraw(double amount)
throws InterruptedException
{
while (balance < amount)
wait();
}
Wait and NotifyAll
- A thread that calls wait is in a blocked state
- It will not be activated by the thread scheduler until it is unblocked
- It is unblocked when another thread calls notifyAll
- When a thread calls notifyAll, all threads waiting on the object
are unblocked
- Only the thread that has the lock can call notifyAll
Restroom wait/notifyAll Analogy
- The thread calling wait corresponds to the person who enters the restroom
and finds there is no toilet paper
- The person then leaves the restroom and waits outside
- Other people may enter and leave, but the first person just waits
- Eventually an attendant enters the restroom, refills the toilet paper, and
shouts a notification
- All the waiting people compete for the restroom
File BankAccountThreadTest.java
Using synchronized methods
File BankAccount.java
Animation
- Animation shows different objects moving or changing as time progresses
- Thread programming is useful in animation
- An algorithm animation helps visualize the steps in the algorithm
Algorithm Animation
- Runs in a separate thread that periodically updates an image of the current
state of the algorithm
- It then pauses so the user can see the change
- After a short time the algorithm thread wakes up and runs to the next point
of interest
- It updates the image again and pauses again
Selection Sort Algorithm Animation
- Items in the algorithm's state
- The array of values
- The size of the already sorted area
- The currently marked element
- To visualize the algorithm
- Show the sorted part of the array in a different color
- Mark the currently visited array element in red.
Selection Sort Algorithm Animation
Selection Sort Algorithm Animation
Selection Sort Algorithm Animation
- Add a draw method to draw the current state of the array
public void draw(Graphics2D g2)
{
int deltaX = applet.getWidth() / a.length;
for (int i = 0; i < a.length; i++)
{
if (i == markedPosition)
g2.setColor(Color.red);
else if (i <= alreadySorted)
g2.setColor(Color.blue);
else
g2.setColor(Color.black);
g2.draw(new Line2D.Double(i * deltaX, 0,
i * deltaX, a[i]));
}
}
Selection Sort Algorithm Animation
Applet to Provide User Interface
Applet to Provide User Interface
Applet to Provide User Interface
- The Applet provides a startAnimation method
- It constructs a SelectionSorter with a new array and a this reference
to the Applet
- It constructs a thread
- The thread's run method calls the sorter's sort method
Applet to Provide User Interface
- startAnimation method
public void startAnimation()
{
class AnimationThread extends Thread
{
public void run()
{
try
{
sorter.sort();
}
catch (InterruptedException exception)
{
}
}
}
int[] values = ArrayUtil.randomIntArray(30, 300);
sorter = new SelectionSorter(values, this);
animation = new AnimationThread();<
animation.start();
}
A Step in the Animation of the Selection Sort Algorithm

File SelectionSortApplet.java
File SelectionSorter