Object-Oriented Design & Patterns
Cay S. Horstmann
Chapter 9
Multithreading
Chapter Topics
- Thread Basics
- Thread Synchronization
- Animation
Threads
- Thread: program unit that is executed independently
- Multiple threads run simultaneously
- Virtual machine executes each thread for short time slice
- Thread scheduler activates, deactivates threads
- Illusion of threads running in parallel
- Multiprocessor computers: threads actually run in parallel
Running Threads
- Define class that implements Runnable
- Runnable has one method
void run()
- Place thread action into run
method
- Construct object of runnable class
- Construct thread from that object
- Start thread
Running Threads
public class MyRunnable implements Runnable
{
public void run()
{
thread action
}
}
...
Runnable r = new MyRunnable();
Thread t = new Thread(t);
t.start();
Thread Example
Thread Example

Thread Example
- Note: output not exactly interleaved
1: Hello, World!
1: Goodbye, World!
2: Hello, World!
2: Goodbye, World!
3: Hello, World!
3: Goodbye, World!
4: Hello, World!
4: Goodbye, World!
5: Hello, World!
5: Goodbye, World!
6: Hello, World!
6: Goodbye, World!
7: Hello, World!
7: Goodbye, World!
8: Goodbye, World!
8: Hello, World!
9: Goodbye, World!
9: Hello, World!
10: Goodbye, World!
10: Hello, World!
Starting Two Threads

Thread States
- Each thread has
- Thread states:
- new (before start
called)
- dead (after run
method exits)
Thread States

Blocked Thread State
- Reasons for blocked state:
- Waiting to acquire lock (later)
- Waiting for notification (later)
- Unblocks only if reason for block goes away
Scheduling Threads
- Scheduler activates new thread if
- a thread has completed its time slice
- a thread has blocked itself
- a thread with higher priority has become runnable
- Scheduler determines new thread to run
- looks only at runnable threads
- picks one with max priority
Terminating Threads
- Thread terminates when run
exits
- Sometimes necessary to terminate running thread
- Don't use deprecated stop
method
- Interrupt thread by calling interrupt
- Thread must cooperate and exit its run
- Thread has chance to clean up
Sensing Interruptions
- Thread could occasionally call
Thread.currentThread().isInterrupted()
- sleep, wait throw InterruptedException when thread
interrupted
- . . . and then the interruption status is cleared!
- More robust: Catch
exception and react to interruption
- Recommendation: Terminate run
when sensing interruption
Sensing Interruptions
public class MyRunnable implements Runnable
{
public void run()
{
try
{
while (...)
{
do work
Thread.sleep(...);
}
}
catch (InterruptedException e) {}
clean up
}
}
Thread Synchronization
- Use bounded queue from chapter 3
- Each producer thread inserts greetings
- Each consumer thread removes greetings
- Two producers, one consumer
Producer Thread
int i = 1;
while (i <= repetitions)
{
if (!queue.isFull())
{
queue.add(i + ": " + greeting); i++;
}
Thread.sleep((int)(Math.random() * DELAY));
}
Consumer Thread
int i = 1;
while (i <= repetitions)
{
if (!queue.isEmpty())
{
Object greeting = queue.removeFirst();
System.out.println(greeting);
i++;
}
Thread.sleep((int)(Math.random() * DELAY));
}
Expected Program Output
1: Hello, World!
1: Goodbye, World!
2: Hello, World!
3: Hello, World!
...
99: Goodbye, World!
100: Goodbye, World!
Why is Output Corrupted?
- Sometimes program gets stuck and doesn't complete
- Can see problem better when turning debugging on
queue.setDebug(true);
Race Condition Scenario
- First thread calls add
and executes
elements[tail] = anObject;
- First thread at end of time slice
- Second thread calls add
and executes
elements[tail] = anObject;
tail++;
- Second thread at end of time slice
- First thread executes
tail++;
Race Condition Scenario

Object Locks
- Each object has a lock
- Thread can lock, unlock object
- No other thread can lock object until unlocked
- Use synchronized
method
- Calling synchronized method locks implicit parameter
- No other thread can call another synchronized method on same
object
- Place thread-sensitive code inside synchronized methods
public synchronized void add(Object
anObject) { ... }
Scenario with Synchronized Methods
- First thread calls add
and executes
elements[tail] = anObject;
- First thread at end of time slice
- Second thread tries to call add,
blocks
- First thread executes
tail++;
- First thread completes add,
unlocks queue
- Second thread unblocked
- Second thread calls add
Visualizing Locks
- Object = phone booth
- Thread = person
- Locked object = closed booth
- Blocked thread = person waiting for booth to open
Visualizing Locks

Deadlocks
- Not enough to synchronize add,removeFirst
- if (!queue.isFull())
queue.add(...);
can still be interrupted
- Must move test inside add
method
- What should add do
if queue is full?
Deadlocks
- Consumer will remove objects
- Producer needs to wait
- Producer can't go to sleep inside locked object
- Person sleeping in phone booth, waiting for technician?
Avoiding Deadlocks
- Call wait in add method:
public synchronized void
add(Object anObject)
throws InterruptedException
{
while (isFull())
wait();
}
- Waiting thread is blocked
- Waiting thread is added to wait
set of object
Avoiding Deadlocks
- To unblock waiting thread, some other thread calls notifyAll
- Must be called on same object
- Call when state changes
public synchronized Object
removeFirst()
{
...
notifyAll();
}
- All waiting threads removed from wait set, unblocked
- Ch9/queue2/Queue.java
Algorithm Animation
- Use thread to make progress in algorithm
- Display algorithm state
- Example: Animate Ch9/animation/MergeSorter.java
- Pause inside compare
method
- Pass custom comparator
Comparator comp = new
Comparator()
{
public void compare(Object o1, Object o2)
{
draw
current state
pause thread
return comparison result
}
};
Algorithm Animation

Algorithm Animation
Pausing and Running the Animation
- Want to pause animation until button is clicked
- Need to coordinate UI thread, animation thread
- Easier to understand coordination with custom object
- Both threads query, manipulate gate
Gate
- Works like a security gate
- Sorter thread = car approaching gate
- Passes through if gate open, pauses otherwise
- Animation thread = security guard
- Step button opens gate to let one car through
- Run button deactivates gate--alway open
Gate

Pausing and Running the Animation
Animation Classes
