Upload
joel-hodge
View
218
Download
4
Embed Size (px)
Citation preview
Threads
Objectives
• You must be able to answer the following questions– What code does a thread execute?– What states can a thread be in?– How does a thread change its state?– How does synchronization work?
Java ThreadsA Quick Definition:
A Thread is a lightweight process (chunk of code) that can act independently of another any other code in an application. They allow us to give the illusion that more than one process is running at the same time.
How-To in Java:
Subclass java.lang.Thread, or implement the interface Runnable and provide a method:
public void run(){
// threaded code goes here}
The method run() is started via a call to “start()”. (One can also override start(), but this is not always necessary.)
Thread Objects
• As is everything else, threads in Java are represented as objects.
• The code that a thread executes is contained in its run() method.– There is nothing special about run, anyone can
call it.
• To make a thread eligible for running you call its start() method
Example
public class CounterThread extends Thread { public void run() { for ( int i=0; i<10; i++) System.out.println(“Count: “ + i); }
public static void main(String args[]) { CounterThread ct = new CounterThread(); ct.start(); }}
Interface Runnable
• Classes that implement Runnable can also be run as separate threads
• Runnable classes have a run() method
• In this case you create a thread specifying the Runnable object as the constructor argument
Examplepublic class DownCounter implements Runnable { public void run() { for (int i=10; i>0; i--) System.out.println(“Down: “+ i); }
public static void main(String args[]) { DownCounter ct = new DownCounter(); Thread t = new Thread(ct);
t.start(); }}
Thread Creation Diagram
Thread t = new BThread();
t.start();
doMoreStuff();
Object A
BThread() {}
void start() {// create thread
}
void run() {doSomething();
}
Object BThread (extends Thread)
Thread Creation Diagram
Thread t = new BThread();
t.start();
doMoreStuff();
Object A
BThread() {}
void start() {// create thread
}
void run() {doSomething();
}
Object BThread (extends Thread)
Thread Creation Diagram
Thread t = new BThread();
t.start();
doMoreStuff();
Object A
BThread() {}
void start() {// create thread
}
void run() {doSomething();
}
Object BThread (extends Thread)
Thread Creation Diagram
Thread t = new BThread();
t.start();
doMoreStuff();
Object A
BThread() {}
void start() {// create thread
}
void run() {doSomething();
}
Object BThread (extends Thread)
Thread Creation Diagram
Thread t = new BThread();
t.start();
doMoreStuff();
Object A
BThread() {}
void start() {// create thread
}
void run() {doSomething();
}
Object BThread (extends Thread)
Thread Creation Diagram
Thread t = new BThread();
t.start();
doMoreStuff();
Object A
BThread() {}
void start() {// create thread
}
void run() {doSomething();
}
Object BThread (extends Thread)
Thread Creation Diagram
Thread t = new BThread();
t.start();
doMoreStuff();
Object A
BThread() {}
void start() {// create thread
}
void run() {doSomething();
}
Object BThread (extends Thread)
Thread Creation Diagram
Thread t = new BThread();
t.start();
doMoreStuff();
Object A
BThread() {}
void start() {// create thread
}
void run() {doSomething();
}
Object BThread (extends Thread)
Thread Creation Diagram
Thread t = new BThread();
t.start();
doMoreStuff();
Object A
BThread() {}
void start() {// create thread
}
void run() {doSomething();
}
Object BThread (extends Thread)
Thread Lifecycle
Born
BlockedRunnable
Dead
stop()
start()
stop()
Active
block on I/O
I/O available
JVM
sleep(500)
wake up
suspend()
resume()
wait
notify
Blocking Threads
• When reading from a stream, if input is not available, the thread will block
• Thread is suspended (“blocked”) until I/O is available
• Allows other threads to automatically activate• When I/O available, thread wakes back up again
– Becomes “runnable”
– Not to be confused with the Runnable interface
Thread Scheduling
• In general, the runnable thread with the highest priority is active (running)
• Java is priority-preemptive– If a high-priority thread wakes up, and a low-priority
thread is running– Then the high-priority thread gets to run
immediately
• Allows on-demand processing– Efficient use of CPU
Thread Starvation
• If a high priority thread never blocks
• Then all other threads will starve
• Must be clever about thread priority
Thread Priorities: General Strategies
• Threads that have more to do should get lower priority
• High priority for short tasks
• Give your I/O-bound threads high priority– Wake up, immediately process data, go back to
waiting for I/O
Race Conditions
• Two threads are simultaneously modifying a single object
• Both threads “race” to store their value
• In the end, the last one there “wins the race”
• (Actually, both lose)
Race Condition Example
class Account {
int balance;
public void deposit(int val)
{
int newBal;
newBal = balance + val;
balance = newBal;
}
}
Thread Synchronization
• Language keyword: synchronized
• Takes out a monitor lock on an object– Exclusive lock for that thread
• If lock is currently unavailable, thread will block
Thread Synchronization
• Protects access to code, not to data– Make data members private
– Synchronize accessor methods
• Puts a “force field” around the locked object so no other threads can enter
• Actually, it only blocks access to other synchronizing threads
Thread Deadlock
• If two threads are competing for more than one lock
• Example: bank transfer between two accounts– Thread A has a lock on account 1 and wants to
lock account 2
– Thread B has a lock on account 2 and wants to lock account 1
Avoiding Deadlock
• No universal solution
• Ordered lock acquisition
• Check and back off
• Timeout
• Minimize or remove synchronization
Wait and Notify
• Allows two threads to cooperate
• Based on a single shared lock object
Wait and Notify: Code
• Consumer:
synchronized (lock) {
while (!resourceAvailable()) {
lock.wait();
}
consumeResource();
}
Wait and Notify: Code
• Producer:
produceResource();
synchronized (lock) {
lock.notifyAll();
}
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify Sequence
Lock Object
ConsumerThread
ProducerThread
1. synchronized(lock){
2. lock.wait();
3. produceResource()4. synchronized(lock) {5. lock.notify();6.}
7. Reacquire lock8. Return from wait()
9. consumeResource();10. }
Wait/Notify: Details
• Must loop on wait(), in case another thread grabs the resource...– After you are notified– Before you acquire the lock and return from
wait()
• Use lock.notifyAll() if there may be more than one waiting thread
Wait/Notify Example: Blocking Queue
class BlockingQueue extends Queue {
public synchronized Object remove() {
while (isEmpty()) {
wait(); // really this.wait()
}
return super.remove();
}
public synchronized void add(Object o) {
super.add(o);
notifyAll(); // this.notifyAll()
}
}