You are on page 1of 29

IEG 4180

Network Software Design and Programming

Java Multithread Programming


Contents Copyright Jack Y. B. Lee
All Rights Reserved

• 1. Introduction
• 2. Java Thread APIs
• 3. Creating a New Thread
• 4. Thread Scheduling
• 5. Thread Synchronization
• 6. Thread Coordination
• 7. Swing and Multithreading
• References

IEG4180: Network Software Design and Programming - Java Multithread Programming 2


1. Introduction Copyright Jack Y. B. Lee
All Rights Reserved

• Thread Support
Š Java supports multithreading at the language/JVM level.
Š Any platform supporting Java supports multithreading.
• Implementations

Java Multithread Application Java Multithread Application

Java Thread Classes Java Thread Classes

Java Virtual Machine


Internal Implementation
of Threads (green threads)

Operating System Native Thread API


Java Virtual Machine (e.g., POSIX Pthreads, Win32 threads)

JVM-Implemented Threads Using Native Threads

IEG4180: Network Software Design and Programming - Java Multithread Programming 3


2. Java Thread APIs Copyright Jack Y. B. Lee
All Rights Reserved

• Class/Interface
Š A Thread class for sub-classing threaded-classes;
Š A Runnable interface to work around single-inheritance;
• Thread Synchronization
Š The synchronized keyword for mutual exclusion;
Š Special methods (wait(), notify(), etc.) of the Object class for
threads coordination;
• Thread Management
Š A ThreadGroup class for managing threads in groups;
Š A ThreadLocal class for implementing thread-local storage.

IEG4180: Network Software Design and Programming - Java Multithread Programming 4


3. Creating a New Thread Copyright Jack Y. B. Lee
All Rights Reserved

• Method 1: Subclassing the Thread Class


Š Step 1 - Subclass from the Thread class
class ThreadSend extends Thread {
public void run( ) {
// …
}
}

The new thread will start execution from the run() method.
Thread terminates when returned from run().

Š Step 2 - Create the new thread


ThreadSend sender = new ThreadSend(); // Create the thread object
sender.start(); // Create the new thread

The start() method is inherited from class Thread.


This call start the new thread’s execution from the run() method.

IEG4180: Network Software Design and Programming - Java Multithread Programming 5


3. Creating a New Thread Copyright Jack Y. B. Lee
All Rights Reserved

• Method 2: Implementing the Runnable Interface


Š Step 1 - Implements the Runnable interface
class ThreadSend implements Runnable {
public void run( ) {
// …
}
}

The new thread will start execution from the run() method.
Thread terminates when returned from run().

Š Step 2 - Start the new thread via a Thread object


Thread thread_1 = new Thread(new ThreadSend());
thread_1.start();

Creates a new Thread object and pass it the ThreadSend object.


This can be done because the Thread object is expecting a Runnable object.

IEG4180: Network Software Design and Programming - Java Multithread Programming 6


3. Creating a New Thread Copyright Jack Y. B. Lee
All Rights Reserved

• Subclassing Thread v.s. Implementing Runnable


Š Implementing the Runnable interface is required if your class
already has a superclass.
Š Otherwise subclassing Thread is generally simpler.
• You can call Thread’s methods such as sleep() and
setPriority() within the run() method.
Š Workaround using Thread.currentThread():

class ThreadSend implements Runnable {


public void run( ) {
// sleep(1000); <- this won’t work.
Thread.currentThread().sleep(1000); // this is ok.
}
}

You can call Thread.currentThread() anywhere because it is a static method.

IEG4180: Network Software Design and Programming - Java Multithread Programming 7


4. Thread Scheduling Copyright Jack Y. B. Lee
All Rights Reserved

• Thread Priorities
Š Initial priority is the same as the creating thread.
Š Ranges of thread priority:
static int MAX_PRIORITY
- The maximum priority that a thread can have.
static int MIN_PRIORITY
- The minimum priority that a thread can have.
static int NORM_PRIORITY
- The default priority that is assigned to a thread.

Š Methods for get/set thread priority:


public final int getPriority()
public final void setPriority(int newPriority)

Š Note that the thread priority affects scheduling of threads within the
same process only.
Š The JVM does not guarantee anything based on thread priorities.

IEG4180: Network Software Design and Programming - Java Multithread Programming 8


5. Thread Synchronization Copyright Jack Y. B. Lee
All Rights Reserved

• Waiting for Threads To Terminate


void Thread::join()
void Thread::join(long millis)
void Thread::join(long millis, int nanos)

Thread #1

Thread #2 Thread #2 Thread #2

Thread #3 Thread #3

Thread #4

Thread4.join();
Thread3.join();
Thread2.join();

IEG4180: Network Software Design and Programming - Java Multithread Programming 9


5. Thread Synchronization Copyright Jack Y. B. Lee
All Rights Reserved

• Mutual Exclusion
Š How?
• Java supports a synchronized keyword.
• It’s applicable to a class, a method, and a block of code.
Š Object-based Synchronization
• Any Java objects can be used for synchronization.
• Built-in types (int, float, etc.) cannot be used.

synchronize(obj)

An object is being used as a mutex for synchronization.


The object (mutex) can be acquired by at most one thread at any one time.

IEG4180: Network Software Design and Programming - Java Multithread Programming 10


5. Thread Synchronization Copyright Jack Y. B. Lee
All Rights Reserved

• Mutual Exclusion
Š Synchronization on a Block Level

class ThreadSend {
static Object Lock = new Object(); // for sync
public void doSomething( ) {
// …
synchronized(Lock) {
// protected code …
}
}
}

At anytime at most one thread can enter this block of code.


This is true even if multiple instances of ThreadSend have been created. (Why?)

IEG4180: Network Software Design and Programming - Java Multithread Programming 11


5. Thread Synchronization Copyright Jack Y. B. Lee
All Rights Reserved

• Mutual Exclusion
Š Synchronization on a Block Level

blocked
Thread 1
synchronized(Lock) {
Thread 2 ...
}
Thread 3

Lock is static, so only one instance exists


regardless of number of ThreadSend instances.

class ThreadSend {
static Object Lock = new Object(); // for sync
// ...
}

IEG4180: Network Software Design and Programming - Java Multithread Programming 12


5. Thread Synchronization Copyright Jack Y. B. Lee
All Rights Reserved

• Mutual Exclusion
Š Synchronization on a Method Level
• Ensures only one thread can call an object’s method at a time.

class ThreadSend extends Thread {


synchronized void doSomething( ) {
// …
}
}

This is equivalent to synchronized(this).

• So if there are two instances of ThreadSend, then the


doSomething() method in the two instances can be executed by
two different threads concurrently.

IEG4180: Network Software Design and Programming - Java Multithread Programming 13


5. Thread Synchronization Copyright Jack Y. B. Lee
All Rights Reserved

• Mutual Exclusion
Š Synchronization on a Method Level

ThreadSend ts1 = new ThreadSend();


ThreadSend ts2 = new ThreadSend();
// ...

blocked
Thread 1 (ts1)
ts1.doSomething () {
Thread 2 (ts1) ...
}
Thread 3 (ts2)
ts2.doSomething () {
...
}

Thread 2 and 3 can concurrently run doSomething()


because two ThreadSend instances are used.

IEG4180: Network Software Design and Programming - Java Multithread Programming 14


5. Thread Synchronization Copyright Jack Y. B. Lee
All Rights Reserved

• Mutual Exclusion
Š Synchronization on a Class Level
• Ensures only one thread can call a class method at a time.

class ThreadSend extends Thread {


static synchronized void doSomething( ) {
// …
}
}

This is equivalent to synchronized(Class.forName(ThreadSend)).

• So even if there are two instances of ThreadSend, the


doSomething() method still can only be executed by at most one
thread only.

IEG4180: Network Software Design and Programming - Java Multithread Programming 15


5. Thread Synchronization Copyright Jack Y. B. Lee
All Rights Reserved

• Mutual Exclusion
Š Synchronization on a Class Level

ThreadSend ts1 = new ThreadSend();


ThreadSend ts2 = new ThreadSend();
// ...

blocked
Thread 1 (ts2)
ThreadSend.doSomething () {
Thread 2 (ts2) ...
}
Thread 3 (ts1)

IEG4180: Network Software Design and Programming - Java Multithread Programming 16


6. Threads Coordination Copyright Jack Y. B. Lee
All Rights Reserved

• The Producer-Consumer Model Revisited

FIFO Queue
Producer Consumer
Consumer
Consumer

The producer runs in a separate thread.

The consumer(s) also runs in separate threads.

Š Problem #1 - Mutual exclusion in accessing the queue.


Š Solution
• Use the Java synchronized mechanism to control access to the
queue object.

IEG4180: Network Software Design and Programming - Java Multithread Programming 17


6. Threads Coordination Copyright Jack Y. B. Lee
All Rights Reserved

• Producer-Consumer(s) Synchronization
Š Problem #2
• Producer needs to be suspended if the queue is full.

FIFO Queue
Producer X Consumer
Consumer
Consumer

• And it needs to be waked up once the queue has vacant space.

FIFO Queue
Producer Consumer
Consumer
Consumer

IEG4180: Network Software Design and Programming - Java Multithread Programming 18


6. Threads Coordination Copyright Jack Y. B. Lee
All Rights Reserved

• Producer-Consumer(s) Synchronization
Š Problem #3
• Consumer needs to be suspended if the queue is empty.

FIFO Queue
Producer X Consumer
Consumer
Consumer

• And it needs to be waked up once the queue becomes non-


empty.

FIFO Queue
Producer Consumer
Consumer
Consumer

IEG4180: Network Software Design and Programming - Java Multithread Programming 19


6. Threads Coordination Copyright Jack Y. B. Lee
All Rights Reserved

• Producer-Consumer(s) Synchronization
Š Solution to Problem #2 & #3
• The Java Object class implements several special methods for
inter-thread synchronization: wait(), notify().
• wait()
Š Causes current thread to wait until another thread invokes the
notify() method for this object.
• notify()
Š Wakes up a single thread that is waiting on this object's monitor.
Š If multiple threads are waiting on this object, one of them is chosen
to be awakened.
• Using these functions one can implement a semaphore class.

IEG4180: Network Software Design and Programming - Java Multithread Programming 20


6. Threads Coordination Copyright Jack Y. B. Lee
All Rights Reserved

• The java.util.concurrent.Semaphore Class


Š New in JDK 5.0 (formerly 1.5) released in September 2004
Š Semaphore Methods
Semaphore::Acquire()
Blocks until successful.
Semaphore::Acquire(int how_many)
Semaphore::Release()
Semaphore::Release(int how_many)

Š Semaphore Constructors
Semaphore (int initial_count)
Semaphore (int initial_count, boolean fairness_flag)

If set to true blocked-acquiring-threads will be released in first-in-first-out order,


otherwise in unpredictable order (likely last-in-first-out).

IEG4180: Network Software Design and Programming - Java Multithread Programming 21


7. Swing and Multithreading Copyright Jack Y. B. Lee
All Rights Reserved

• Pitfall #1
Š The Swing library manages GUI components in a thread
(event-dispatching thread) separate from your application’s threads.
Š Methods in listener objects are called by Swing in the context of the
event-dispatching thread:

class MyWinListener implements WindowListener {


public void windowClosing(WindowEvent e) {
Swing
// your processing code are being run
(runs in a separate thread) // in the event-dispatching thread!
}
}

• Access to shared data structures with the event-dispatching


thread may have to be synchronized.

IEG4180: Network Software Design and Programming - Java Multithread Programming 22


7. Swing and Multithreading Copyright Jack Y. B. Lee
All Rights Reserved

• Pitfall #2
Š The Swing library is NOT thread-safe!
Š You may not call the Swing library such as creating, or updating GUI
components in your own thread, except within the application
main() method (or applet init() method).
Š Calling the Swing library within a listener method is ok. (why?)

IEG4180: Network Software Design and Programming - Java Multithread Programming 23


7. Swing and Multithreading Copyright Jack Y. B. Lee
All Rights Reserved

• Pitfall #2
Š Example - Periodically Update Statistics
• Incorrect implementation

public class JNetProbe extends javax.swing.JFrame implements Runnable {


// From the Runnable Interface
public void run() {
Runs in the statUpdate thread.

while (bIsRunning) {
UpdateStat(); // update stat display
sleep(100); // wait for 100 ms
}
} offending code
// Statistics Update Function //
public void UpdateStat()
{
// ...
// # of Packets Transferred
str = String.valueOf(num_transferred);
m_JLabel_PacketsTransferred.setText(str);
// ...
}

public static void main (String args[]) {


// ...
// Start a new thread for statistics update
Thread statUpdate = new Thread(this);
// ...
}
}

IEG4180: Network Software Design and Programming - Java Multithread Programming 24


7. Swing and Multithreading Copyright Jack Y. B. Lee
All Rights Reserved

• Pitfall #2
Š Solution
• Swing allows another thread to manually generate an event for
processing in the event-dispatching thread.
• Two methods in the javax.swing.SwingUtilities class:
Š static void invokeAndWait(Runnable doRun)
» Causes doRun.run() to be executed synchronously on the
event-dispatching thread.
Š static void invokeLater(Runnable doRun)
» Causes doRun.run() to be executed asynchronously on the
event-dispatching thread.

class doRun implements Runnable {


public void run() {
// This will be run within the event-dispatching thread.
// Updating GUI here will be safe.
}
}

IEG4180: Network Software Design and Programming - Java Multithread Programming 25


7. Swing and Multithreading Copyright Jack Y. B. Lee
All Rights Reserved

• Pitfall #2
Š Example - Periodically Update Statistics
• Correct implementation

TimerThread

invokeLater(…)

Swing

UpdateCode
(implements Runnable)

context of timer thread context of event-dispatching thread

IEG4180: Network Software Design and Programming - Java Multithread Programming 26


7. Swing and Multithreading Copyright Jack Y. B. Lee
All Rights Reserved

• Pitfall #2
Š Example - Periodically Update Statistics
• Correct implementation

class TimerThread extends Thread {

// Constructor
TimerThread(int refresh_interval, Runnable update_code) {
m_iRefreshInterval = refresh_interval;
m_UpdateCode = update_code;
m_bToQuit = false;
}

// Set Function
void QuitUpdate() { m_bToQuit = true; }

// Thread entry function


public void run() {
// Generates one event to m_UpdateCode every m_RefreshInterval milliseconds
while (!m_bToQuit) {
javax.swing.SwingUtilities.invokeLater(m_UpdateCode);
try {
sleep(m_iRefreshInterval);
} catch (Exception e) { }
}
}
}

IEG4180: Network Software Design and Programming - Java Multithread Programming 27


7. Swing and Multithreading Copyright Jack Y. B. Lee
All Rights Reserved

• Pitfall #2
Š Example - Periodically Update Statistics
• Correct implementation

public class JNetProbe extends javax.swing.JFrame implements Runnable {

// To-be invoked from the event-dispatching thread


public void run() {
UpdateStat(); // update stat display
}

// Constructor
public JNetProbe() {
initComponents ();
pack ();

// ...
m_TimerThread = new TimerThread(100, this);
m_TimerThread.start();
}
}

IEG4180: Network Software Design and Programming - Java Multithread Programming 28


References Copyright Jack Y. B. Lee
All Rights Reserved

• Doug Lea, Concurrent Programming in Java - Design Principles and


Patterns, Second Edition, Sun Microsystems Press, 1999.
• Bil Lewis and Daniel J. Berg, Multithreaded Programming with
Java Technology, Sun Microsystems Press, 2000.

IEG4180: Network Software Design and Programming - Java Multithread Programming 29