1 © 2001-2003 Marty Hall, Larry Brown http://www.corewebprogramming.com
core
programming
Multithreaded
Programming
Multithreaded Programming2 www.corewebprogramming.com
Agenda
• Why threads?
• Approaches for starting threads
– Separate class approach
– Callback approach
• Solving common thread problems
• Synchronizing access to shared resources
• Thread life cycle
• Stopping threads
Multithreaded Programming3 www.corewebprogramming.com
Concurrent Programming
Using Java Threads
• Motivation
– Efficiency
• Downloading network data files
– Convenience
• A clock icon
– Multi-client applications
• HTTP Server, SMTP Server
• Caution
– Significantly harder to debug and maintain
• Two Main Approaches:
– Make a self-contained subclass of Thread with the
behavior you want
– Implement the Runnable interface and put behavior in
the run method of that object
Multithreaded Programming4 www.corewebprogramming.com
Thread Mechanism One:
Making a Thread Subclass
• Create a separate subclass of Thread
– No import statements needed: Thread is in java.lang
• Put the actions to be performed in the run
method of the subclass
– public void run() { … }
• Create an instance of your Thread subclass
– Or lots of instances if you want lots of threads
• Call that instance’s start method
– You put the code in run, but you call start!
Multithreaded Programming5 www.corewebprogramming.com
Thread Mechanism One:
Making a Thread Subclass
public class DriverClass extends SomeClass {
...
public void startAThread() {
// Create a Thread object
ThreadClass thread = new ThreadClass();
// Start it in a separate process
thread.start();
}
}
public class ThreadClass extends Thread {
public void run() {
// Thread behavior here
}
}
Multithreaded Programming6 www.corewebprogramming.com
Thread Mechanism One:
Example
public class Counter extends Thread {
private static int totalNum = 0;
private int currentNum, loopLimit;
public Counter(int loopLimit) {
this.loopLimit = loopLimit;
currentNum = totalNum++;
}
private void pause(double seconds) {
try { Thread.sleep(Math.round(1000.0*seconds)); }
catch(InterruptedException ie) {}
}
...
Multithreaded Programming7 www.corewebprogramming.com
Thread Mechanism One:
Example (Continued)
...
/** When run finishes, the thread exits. */
public void run() {
for(int i=0; i<loopLimit; i++) {
System.out.println("Counter " + currentNum
+ ": " + i);
pause(Math.random()); // Sleep for up to 1 second
}
}
}
Multithreaded Programming8 www.corewebprogramming.com
Thread Mechanism One:
Example (Continued)
public class CounterTest {
public static void main(String[] args) {
Counter c1 = new Counter(5);
Counter c2 = new Counter(5);
Counter c3 = new Counter(5);
c1.start();
c2.start();
c3.start();
}
}
Multithreaded Programming9 www.corewebprogramming.com
Thread Mechanism One: Result
Counter 0: 0
Counter 1: 0
Counter 2: 0
Counter 1: 1
Counter 2: 1
Counter 1: 2
Counter 0: 1
Counter 0: 2
Counter 1: 3
Counter 2: 2
Counter 0: 3
Counter 1: 4
Counter 0: 4
Counter 2: 3
Counter 2: 4
Multithreaded Programming10 www.corewebprogramming.com
Thread Mechanism Two:
Implementing Runnable
• Put the actions to be performed in the run
method of your existing class
• Have class implement Runnable interface
– If your class already extends some other class (e.g.,
Applet), why can't it still extend Thread? Because Java
does not support multiple inheritance.
• Construct an instance of Thread passing in
the existing object (i.e., the Runnable)
– Thread t = new Thread(theRunnableObject);
• Call that Thread’s start method
– t.start();
Multithreaded Programming11 www.corewebprogramming.com
Thread Mechanism Two:
Implementing Runnable (Cont.)
public class ThreadedClass extends AnyClass
implements Runnable {
public void run() {
// Thread behavior here
// If you want to access thread instance
// (e.g. to get private per-thread data), use
// Thread.currentThread().
}
public void startThread() {
Thread t = new Thread(this);
t.start(); // Calls back to run method in this
}
...
}
Multithreaded Programming12 www.corewebprogramming.com
Thread Mechanism Two:
Example
public class Counter2 implements Runnable {
private static int totalNum = 0;
private int currentNum, loopLimit;
public Counter2(int loopLimit) {
this.loopLimit = loopLimit;
currentNum = totalNum++;
Thread t = new Thread(this);
t.start();
}
...
Multithreaded Programming13 www.corewebprogramming.com
Thread Mechanism Two:
Example (Continued)
...
private void pause(double seconds) {
try { Thread.sleep(Math.round(1000.0*seconds)); }
catch(InterruptedException ie) {}
}
public void run() {
for(int i=0; i<loopLimit; i++) {
System.out.println("Counter " + currentNum
+ ": " + i);
pause(Math.random()); // Sleep for up to 1 second
}
}
}
Multithreaded Programming14 www.corewebprogramming.com
Thread Mechanism Two:
Example (Continued)
public class Counter2Test {
public static void main(String[] args) {
Counter2 c1 = new Counter2(5);
Counter2 c2 = new Counter2(5);
Counter2 c3 = new Counter2(5);
}
}
Multithreaded Programming15 www.corewebprogramming.com
Thread Mechanism Two: Result
Counter 0: 0
Counter 1: 0
Counter 2: 0
Counter 1: 1
Counter 1: 2
Counter 0: 1
Counter 1: 3
Counter 2: 1
Counter 0: 2
Counter 0: 3
Counter 1: 4
Counter 2: 2
Counter 2: 3
Counter 0: 4
Counter 2: 4
Multithreaded Programming16 www.corewebprogramming.com
Race Conditions: Example
public class BuggyCounterApplet extends Applet
implements Runnable{
private int totalNum = 0;
private int loopLimit = 5;
public void start() {
Thread t;
for(int i=0; i<3; i++) {
t = new Thread(this);
t.start();
}
}
private void pause(double seconds) {
try { Thread.sleep(Math.round(1000.0*seconds)); }
catch(InterruptedException ie) {}
}
...
Multithreaded Programming17 www.corewebprogramming.com
Race Conditions: Example
(Continued)
...
public void run() {
int currentNum = totalNum;
System.out.println("Setting currentNum to "
+ currentNum);
totalNum = totalNum + 1;
for(int i=0; i<loopLimit; i++) {
System.out.println("Counter "
+ currentNum + ": " + i);
pause(Math.random());
}
}
}
• What's wrong with this code?
Multithreaded Programming18 www.corewebprogramming.com
Race Conditions: Result
• Occasional Output
Setting currentNum to 0
Counter 0: 0
Setting currentNum to 1
Setting currentNum to 1
Counter 0: 1
Counter 1: 0
Counter 1: 0
Counter 0: 2
Counter 0: 3
Counter 1: 1
Counter 0: 4
Counter 1: 1
Counter 1: 2
Counter 1: 3
Counter 1: 2
Counter 1: 3
Counter 1: 4
Counter 1: 4
• Usual Output
Setting currentNum to 0
Counter 0: 0
Setting currentNum to 1
Counter 1: 0
Setting currentNum to 2
Counter 2: 0
Counter 2: 1
Counter 1: 1
Counter 0: 1
Counter 2: 2
Counter 0: 2
Counter 1: 2
Counter 1: 3
Counter 0: 3
Counter 2: 3
Counter 1: 4
Counter 2: 4
Counter 0: 4
Multithreaded Programming19 www.corewebprogramming.com
Race Conditions: Solution?
• Do things in a single step
public void run() {
int currentNum = totalNum++;
System.out.println("Setting currentNum to "
+ currentNum);
for(int i=0; i<loopLimit; i++) {
System.out.println("Counter "
+ currentNum + ": " + i);
pause(Math.random());
}
}
Multithreaded Programming20 www.corewebprogramming.com
Arbitrating Contention for
Shared Resources
• Synchronizing a Section of Code
synchronized(someObject) {
code
}
• Normal interpretation
– Once a thread enters the code, no other thread can enter
until the first thread exits.
• Stronger interpretation
– Once a thread enters the code, no other thread can enter
any section of code that is synchronized using the same
“lock” tag
Multithreaded Programming21 www.corewebprogramming.com
Arbitrating Contention for
Shared Resources
• Synchronizing an Entire Method
public synchronized void someMethod() {
body
}
• Note that this is equivalent to
public void someMethod() {
synchronized(this) {
body
}
}
Multithreaded Programming22 www.corewebprogramming.com
Common Synchronization Bug
• What’s wrong with this class?
public class SomeThreadedClass extends Thread {
private static RandomClass someSharedObject;
...
public synchronized void doSomeOperation() {
accessSomeSharedObject();
}
...
public void run() {
while(someCondition) {
doSomeOperation(); // Accesses shared data
doSomeOtherOperation();// No shared data
}
}
}
Multithreaded Programming23 www.corewebprogramming.com
Synchronization Solution
• Solution 1: synchronize on the shared data
public void doSomeOperation() {
synchronized(someSharedObject) {
accessSomeSharedObject();
}
}
• Solution 2: synchronize on the class object
public void doSomeOperation() {
synchronized(SomeThreadedClass.class) {
accessSomeSharedObject();
}
}
– Note that if you synchronize a static method, the lock is the
corresponding Class object, not this
Multithreaded Programming24 www.corewebprogramming.com
Synchronization Solution
(Continued)
• Solution 3: synchronize on arbitrary object
public class SomeThreadedClass extends Thread {
private static Object lockObject
= new Object();
...
public void doSomeOperation() {
synchronized(lockObject) {
accessSomeSharedObject();
}
}
...
}
– Why doesn't this problem usually occur with Runnable?
Multithreaded Programming25 www.corewebprogramming.com
Thread Lifecycle
new
wait()
yield()
notify()
dispatch
ready
start()
running
waiting
blocked
sleeping
sleep()
Block on I/O
times expires
or interrupted
I/O completed
deadrun completes
Multithreaded Programming26 www.corewebprogramming.com
Useful Thread Constructors
• Thread()
– Default version you get when you call constructor of your
custom Thread subclass.
• Thread(Runnable target)
– Creates a thread, that, once started, will execute the run
method of the target
• Thread(ThreadGroup group,
Runnable target)
– Creates a thread and places it in the specified thread group
– A ThreadGroup is a collection of threads that can be
operated on as a set
• Thread(String name)
– Creates a thread with the given name
– Useful for debugging
Multithreaded Programming27 www.corewebprogramming.com
Thread Priorities
• A thread’s default priority is the same as the
creating thread
• Thread API defines three thread priorities
•Thread.MAX_PRIORITY (typically 10)
•Thread.NORM_PRIORITY (typically 5)
•Thread.MIN_PRIORITY (typically 1)
• Problems
– A Java thread priority may map differently to the thread
priorities of the underlying OS
• Solaris has 232–1 priority level; Windows NT has 7
user priority levels
– Starvation can occur for lower-priority threads if the
higher-priority threads never terminate, sleep, or wait for
I/O
Multithreaded Programming28 www.corewebprogramming.com
Useful Thread Methods
• currentThread
– Returns a reference to the currently executing thread
– This is a static method that can be called by arbitrary methods,
not just from within a Thread object
• I.e., anyone can call Thread.currentThread
• interrupt
– One of two outcomes:
• If the thread is executing join, sleep, or wait, an
InterruptedException is thrown
• Sets a flag, from which the interrupted thread can check
(isInterrupted)
• interrupted
– Checks whether the currently executing thread has a request for
interruption (checks flag) and clears the flag
Multithreaded Programming29 www.corewebprogramming.com
Useful Thread Methods
(Continued)
• isInterrupted
– Simply checks whether the thread’s interrupt flag has
been set (does not modify the flag)
• Reset the flag by calling interrupted from within
the run method of the flagged thread
• join
– Joins to another thread by simply waiting (sleeps) until
the other thread has completed execution
• isDaemon/setDaemon
– Determines or set the thread to be a daemon
– A Java program will exit when the only active threads
remaining are daemon threads
Multithreaded Programming30 www.corewebprogramming.com
Useful Thread Methods
(Continued)
• start
– Initializes the thread and then calls run
– If the thread was constructed by providing a Runnable,
then start calls the run method of that Runnable
• run
– The method in which a created thread will execute
– Do not call run directly; call start on the thread object
– When run completes the thread enters a dead state and
cannot be restarted
Multithreaded Programming31 www.corewebprogramming.com
Useful Thread Methods
(Continued)
• sleep
– Causes the currently executing thread to do a
nonbusy wait for at least the amount of time
(milliseconds), unless interrupted
– As a static method, may be called for nonthreaded
applications as well
• I.e., anyone can call Thread.sleep
• Note that sleep throws InterruptedException. Need
try/catch
• yield
– Allows any other threads of the same or higher
priority to execute (moves itself to the end of the
priority queue)
– If all waiting threads have a lower priority, then the
yielding thread remains on the CPU
Multithreaded Programming32 www.corewebprogramming.com
Useful Thread Methods
(Continued)
• wait/waitForAll
– Releases the lock for other threads and suspends itself
(placed in a wait queue associated with the lock)
– Thread can be restarted through notify or notifyAll
– These methods must be synchronized on the lock object of
importance
• notify/notifyAll
– Wakes up all threads waiting for the lock
– A notified doesn’t begin immediate execution, but is placed in
the runnable thread queue
Multithreaded Programming33 www.corewebprogramming.com
Stopping a Thread
public class ThreadExample implements Runnable {
private boolean running;
public ThreadExample()
Thread thread = new Thread(this);
thread.start();
}
public void run(){
running = true;
while (running) {
...
}
doCleanup();
}
public void setRunning(boolean running) {
this.running = running;
}
}
Multithreaded Programming34 www.corewebprogramming.com
Signaling with wait and notify
public class ConnectionPool implements Runnable {
...
public synchronized Connection getConnection() {
if (availableConnections.isEmpty()) {
try {
wait();
} catch(InterruptedException ie) {}
// Someone freed up a connection, so try again.
return(getConnection());
} else {
// Get available connection
...
return(connection)
}
}
Multithreaded Programming35 www.corewebprogramming.com
Signaling with wait and notify
(Continued)
public synchronized void free(Connection connection) {
busyConnections.removeElement(connection);
availableConnections.addElement(connection);
// Wake up threads that are waiting
// for a connection
notifyAll();
}
...
}
Multithreaded Programming36 www.corewebprogramming.com
Summary
• Achieve multithreaded behavior by
– Inheriting directly from Thread
(separate class approach)
– Implementing the Runnable interface
(callback approach)
• In either case, put your code in the run
method. Call start on the Thread object.
• Avoid race conditions by placing the shared
resource in a synchronized block
• You can’t restart a dead thread
• Stop threads by setting a flag that the
thread's run method checks
37 © 2001-2003 Marty Hall, Larry Brown http://www.corewebprogramming.com
core
programming
Questions?

13multithreaded Programming

  • 1.
    1 © 2001-2003Marty Hall, Larry Brown http://www.corewebprogramming.com core programming Multithreaded Programming
  • 2.
    Multithreaded Programming2 www.corewebprogramming.com Agenda •Why threads? • Approaches for starting threads – Separate class approach – Callback approach • Solving common thread problems • Synchronizing access to shared resources • Thread life cycle • Stopping threads
  • 3.
    Multithreaded Programming3 www.corewebprogramming.com ConcurrentProgramming Using Java Threads • Motivation – Efficiency • Downloading network data files – Convenience • A clock icon – Multi-client applications • HTTP Server, SMTP Server • Caution – Significantly harder to debug and maintain • Two Main Approaches: – Make a self-contained subclass of Thread with the behavior you want – Implement the Runnable interface and put behavior in the run method of that object
  • 4.
    Multithreaded Programming4 www.corewebprogramming.com ThreadMechanism One: Making a Thread Subclass • Create a separate subclass of Thread – No import statements needed: Thread is in java.lang • Put the actions to be performed in the run method of the subclass – public void run() { … } • Create an instance of your Thread subclass – Or lots of instances if you want lots of threads • Call that instance’s start method – You put the code in run, but you call start!
  • 5.
    Multithreaded Programming5 www.corewebprogramming.com ThreadMechanism One: Making a Thread Subclass public class DriverClass extends SomeClass { ... public void startAThread() { // Create a Thread object ThreadClass thread = new ThreadClass(); // Start it in a separate process thread.start(); } } public class ThreadClass extends Thread { public void run() { // Thread behavior here } }
  • 6.
    Multithreaded Programming6 www.corewebprogramming.com ThreadMechanism One: Example public class Counter extends Thread { private static int totalNum = 0; private int currentNum, loopLimit; public Counter(int loopLimit) { this.loopLimit = loopLimit; currentNum = totalNum++; } private void pause(double seconds) { try { Thread.sleep(Math.round(1000.0*seconds)); } catch(InterruptedException ie) {} } ...
  • 7.
    Multithreaded Programming7 www.corewebprogramming.com ThreadMechanism One: Example (Continued) ... /** When run finishes, the thread exits. */ public void run() { for(int i=0; i<loopLimit; i++) { System.out.println("Counter " + currentNum + ": " + i); pause(Math.random()); // Sleep for up to 1 second } } }
  • 8.
    Multithreaded Programming8 www.corewebprogramming.com ThreadMechanism One: Example (Continued) public class CounterTest { public static void main(String[] args) { Counter c1 = new Counter(5); Counter c2 = new Counter(5); Counter c3 = new Counter(5); c1.start(); c2.start(); c3.start(); } }
  • 9.
    Multithreaded Programming9 www.corewebprogramming.com ThreadMechanism One: Result Counter 0: 0 Counter 1: 0 Counter 2: 0 Counter 1: 1 Counter 2: 1 Counter 1: 2 Counter 0: 1 Counter 0: 2 Counter 1: 3 Counter 2: 2 Counter 0: 3 Counter 1: 4 Counter 0: 4 Counter 2: 3 Counter 2: 4
  • 10.
    Multithreaded Programming10 www.corewebprogramming.com ThreadMechanism Two: Implementing Runnable • Put the actions to be performed in the run method of your existing class • Have class implement Runnable interface – If your class already extends some other class (e.g., Applet), why can't it still extend Thread? Because Java does not support multiple inheritance. • Construct an instance of Thread passing in the existing object (i.e., the Runnable) – Thread t = new Thread(theRunnableObject); • Call that Thread’s start method – t.start();
  • 11.
    Multithreaded Programming11 www.corewebprogramming.com ThreadMechanism Two: Implementing Runnable (Cont.) public class ThreadedClass extends AnyClass implements Runnable { public void run() { // Thread behavior here // If you want to access thread instance // (e.g. to get private per-thread data), use // Thread.currentThread(). } public void startThread() { Thread t = new Thread(this); t.start(); // Calls back to run method in this } ... }
  • 12.
    Multithreaded Programming12 www.corewebprogramming.com ThreadMechanism Two: Example public class Counter2 implements Runnable { private static int totalNum = 0; private int currentNum, loopLimit; public Counter2(int loopLimit) { this.loopLimit = loopLimit; currentNum = totalNum++; Thread t = new Thread(this); t.start(); } ...
  • 13.
    Multithreaded Programming13 www.corewebprogramming.com ThreadMechanism Two: Example (Continued) ... private void pause(double seconds) { try { Thread.sleep(Math.round(1000.0*seconds)); } catch(InterruptedException ie) {} } public void run() { for(int i=0; i<loopLimit; i++) { System.out.println("Counter " + currentNum + ": " + i); pause(Math.random()); // Sleep for up to 1 second } } }
  • 14.
    Multithreaded Programming14 www.corewebprogramming.com ThreadMechanism Two: Example (Continued) public class Counter2Test { public static void main(String[] args) { Counter2 c1 = new Counter2(5); Counter2 c2 = new Counter2(5); Counter2 c3 = new Counter2(5); } }
  • 15.
    Multithreaded Programming15 www.corewebprogramming.com ThreadMechanism Two: Result Counter 0: 0 Counter 1: 0 Counter 2: 0 Counter 1: 1 Counter 1: 2 Counter 0: 1 Counter 1: 3 Counter 2: 1 Counter 0: 2 Counter 0: 3 Counter 1: 4 Counter 2: 2 Counter 2: 3 Counter 0: 4 Counter 2: 4
  • 16.
    Multithreaded Programming16 www.corewebprogramming.com RaceConditions: Example public class BuggyCounterApplet extends Applet implements Runnable{ private int totalNum = 0; private int loopLimit = 5; public void start() { Thread t; for(int i=0; i<3; i++) { t = new Thread(this); t.start(); } } private void pause(double seconds) { try { Thread.sleep(Math.round(1000.0*seconds)); } catch(InterruptedException ie) {} } ...
  • 17.
    Multithreaded Programming17 www.corewebprogramming.com RaceConditions: Example (Continued) ... public void run() { int currentNum = totalNum; System.out.println("Setting currentNum to " + currentNum); totalNum = totalNum + 1; for(int i=0; i<loopLimit; i++) { System.out.println("Counter " + currentNum + ": " + i); pause(Math.random()); } } } • What's wrong with this code?
  • 18.
    Multithreaded Programming18 www.corewebprogramming.com RaceConditions: Result • Occasional Output Setting currentNum to 0 Counter 0: 0 Setting currentNum to 1 Setting currentNum to 1 Counter 0: 1 Counter 1: 0 Counter 1: 0 Counter 0: 2 Counter 0: 3 Counter 1: 1 Counter 0: 4 Counter 1: 1 Counter 1: 2 Counter 1: 3 Counter 1: 2 Counter 1: 3 Counter 1: 4 Counter 1: 4 • Usual Output Setting currentNum to 0 Counter 0: 0 Setting currentNum to 1 Counter 1: 0 Setting currentNum to 2 Counter 2: 0 Counter 2: 1 Counter 1: 1 Counter 0: 1 Counter 2: 2 Counter 0: 2 Counter 1: 2 Counter 1: 3 Counter 0: 3 Counter 2: 3 Counter 1: 4 Counter 2: 4 Counter 0: 4
  • 19.
    Multithreaded Programming19 www.corewebprogramming.com RaceConditions: Solution? • Do things in a single step public void run() { int currentNum = totalNum++; System.out.println("Setting currentNum to " + currentNum); for(int i=0; i<loopLimit; i++) { System.out.println("Counter " + currentNum + ": " + i); pause(Math.random()); } }
  • 20.
    Multithreaded Programming20 www.corewebprogramming.com ArbitratingContention for Shared Resources • Synchronizing a Section of Code synchronized(someObject) { code } • Normal interpretation – Once a thread enters the code, no other thread can enter until the first thread exits. • Stronger interpretation – Once a thread enters the code, no other thread can enter any section of code that is synchronized using the same “lock” tag
  • 21.
    Multithreaded Programming21 www.corewebprogramming.com ArbitratingContention for Shared Resources • Synchronizing an Entire Method public synchronized void someMethod() { body } • Note that this is equivalent to public void someMethod() { synchronized(this) { body } }
  • 22.
    Multithreaded Programming22 www.corewebprogramming.com CommonSynchronization Bug • What’s wrong with this class? public class SomeThreadedClass extends Thread { private static RandomClass someSharedObject; ... public synchronized void doSomeOperation() { accessSomeSharedObject(); } ... public void run() { while(someCondition) { doSomeOperation(); // Accesses shared data doSomeOtherOperation();// No shared data } } }
  • 23.
    Multithreaded Programming23 www.corewebprogramming.com SynchronizationSolution • Solution 1: synchronize on the shared data public void doSomeOperation() { synchronized(someSharedObject) { accessSomeSharedObject(); } } • Solution 2: synchronize on the class object public void doSomeOperation() { synchronized(SomeThreadedClass.class) { accessSomeSharedObject(); } } – Note that if you synchronize a static method, the lock is the corresponding Class object, not this
  • 24.
    Multithreaded Programming24 www.corewebprogramming.com SynchronizationSolution (Continued) • Solution 3: synchronize on arbitrary object public class SomeThreadedClass extends Thread { private static Object lockObject = new Object(); ... public void doSomeOperation() { synchronized(lockObject) { accessSomeSharedObject(); } } ... } – Why doesn't this problem usually occur with Runnable?
  • 25.
    Multithreaded Programming25 www.corewebprogramming.com ThreadLifecycle new wait() yield() notify() dispatch ready start() running waiting blocked sleeping sleep() Block on I/O times expires or interrupted I/O completed deadrun completes
  • 26.
    Multithreaded Programming26 www.corewebprogramming.com UsefulThread Constructors • Thread() – Default version you get when you call constructor of your custom Thread subclass. • Thread(Runnable target) – Creates a thread, that, once started, will execute the run method of the target • Thread(ThreadGroup group, Runnable target) – Creates a thread and places it in the specified thread group – A ThreadGroup is a collection of threads that can be operated on as a set • Thread(String name) – Creates a thread with the given name – Useful for debugging
  • 27.
    Multithreaded Programming27 www.corewebprogramming.com ThreadPriorities • A thread’s default priority is the same as the creating thread • Thread API defines three thread priorities •Thread.MAX_PRIORITY (typically 10) •Thread.NORM_PRIORITY (typically 5) •Thread.MIN_PRIORITY (typically 1) • Problems – A Java thread priority may map differently to the thread priorities of the underlying OS • Solaris has 232–1 priority level; Windows NT has 7 user priority levels – Starvation can occur for lower-priority threads if the higher-priority threads never terminate, sleep, or wait for I/O
  • 28.
    Multithreaded Programming28 www.corewebprogramming.com UsefulThread Methods • currentThread – Returns a reference to the currently executing thread – This is a static method that can be called by arbitrary methods, not just from within a Thread object • I.e., anyone can call Thread.currentThread • interrupt – One of two outcomes: • If the thread is executing join, sleep, or wait, an InterruptedException is thrown • Sets a flag, from which the interrupted thread can check (isInterrupted) • interrupted – Checks whether the currently executing thread has a request for interruption (checks flag) and clears the flag
  • 29.
    Multithreaded Programming29 www.corewebprogramming.com UsefulThread Methods (Continued) • isInterrupted – Simply checks whether the thread’s interrupt flag has been set (does not modify the flag) • Reset the flag by calling interrupted from within the run method of the flagged thread • join – Joins to another thread by simply waiting (sleeps) until the other thread has completed execution • isDaemon/setDaemon – Determines or set the thread to be a daemon – A Java program will exit when the only active threads remaining are daemon threads
  • 30.
    Multithreaded Programming30 www.corewebprogramming.com UsefulThread Methods (Continued) • start – Initializes the thread and then calls run – If the thread was constructed by providing a Runnable, then start calls the run method of that Runnable • run – The method in which a created thread will execute – Do not call run directly; call start on the thread object – When run completes the thread enters a dead state and cannot be restarted
  • 31.
    Multithreaded Programming31 www.corewebprogramming.com UsefulThread Methods (Continued) • sleep – Causes the currently executing thread to do a nonbusy wait for at least the amount of time (milliseconds), unless interrupted – As a static method, may be called for nonthreaded applications as well • I.e., anyone can call Thread.sleep • Note that sleep throws InterruptedException. Need try/catch • yield – Allows any other threads of the same or higher priority to execute (moves itself to the end of the priority queue) – If all waiting threads have a lower priority, then the yielding thread remains on the CPU
  • 32.
    Multithreaded Programming32 www.corewebprogramming.com UsefulThread Methods (Continued) • wait/waitForAll – Releases the lock for other threads and suspends itself (placed in a wait queue associated with the lock) – Thread can be restarted through notify or notifyAll – These methods must be synchronized on the lock object of importance • notify/notifyAll – Wakes up all threads waiting for the lock – A notified doesn’t begin immediate execution, but is placed in the runnable thread queue
  • 33.
    Multithreaded Programming33 www.corewebprogramming.com Stoppinga Thread public class ThreadExample implements Runnable { private boolean running; public ThreadExample() Thread thread = new Thread(this); thread.start(); } public void run(){ running = true; while (running) { ... } doCleanup(); } public void setRunning(boolean running) { this.running = running; } }
  • 34.
    Multithreaded Programming34 www.corewebprogramming.com Signalingwith wait and notify public class ConnectionPool implements Runnable { ... public synchronized Connection getConnection() { if (availableConnections.isEmpty()) { try { wait(); } catch(InterruptedException ie) {} // Someone freed up a connection, so try again. return(getConnection()); } else { // Get available connection ... return(connection) } }
  • 35.
    Multithreaded Programming35 www.corewebprogramming.com Signalingwith wait and notify (Continued) public synchronized void free(Connection connection) { busyConnections.removeElement(connection); availableConnections.addElement(connection); // Wake up threads that are waiting // for a connection notifyAll(); } ... }
  • 36.
    Multithreaded Programming36 www.corewebprogramming.com Summary •Achieve multithreaded behavior by – Inheriting directly from Thread (separate class approach) – Implementing the Runnable interface (callback approach) • In either case, put your code in the run method. Call start on the Thread object. • Avoid race conditions by placing the shared resource in a synchronized block • You can’t restart a dead thread • Stop threads by setting a flag that the thread's run method checks
  • 37.
    37 © 2001-2003Marty Hall, Larry Brown http://www.corewebprogramming.com core programming Questions?