Java Threads

Multithreading was designed into Java from the very beginning. You'll see support for multithreading in special keywords and in a number of classes in the Java Standard API. Understanding threading is a very important part of being an accomplished Java developer.

Thread Objects

Every thread in the JVM is represented by a Java object of class Thread.

A snippet of the class java.lang.thread:

package java.lang;
public class Thread implements Runnable {

    public final static int MIN_PRIORITY = 1;
    public final static int NORM_PRIORITY = 5;
    public final static int MAX_PRIORITY = 10;

    public Thread() {...}
    public Thread(Runnable target) {...}
    public Thread(ThreadGroup group, Runnable target) {...}
    public Thread(String name) {...}
    public Thread(ThreadGroup group, String name) {...}
    public Thread(Runnable target, String name) {...}
    public Thread(ThreadGroup group, Runnable target, String name) {...}
    public Thread(ThreadGroup group, Runnable target, String name, long stackSize) {...}

    public synchronized void start() {...}
    public void run() {...}
    public final void suspend() {...}
    public final void resume() {...}
    public void interrupt() {...}
    public static boolean interrupted() {...}
    public boolean isInterrupted() {...}
    public final void stop() {...}
    public void destroy() {...}
    public final native boolean isAlive();

    public final String getName() {...}
    public final void setName(String name) {...}
    public final int getPriority() {...}
    public final void setPriority(int newPriority) {...}
    public final boolean isDaemon() {...}
    public final void setDaemon(boolean on) {...}
    public final ThreadGroup getThreadGroup() {...}
    public ClassLoader getContextClassLoader() {...}
    public enum State {NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED}
    public State getState() {...}
    public long getId() {...}

    public static int activeCount() {...}
    public static int enumerate(Thread tarray[]) {...}

    public static native boolean holdsLock(Object obj);

    public static native Thread currentThread();
    public static native void yield();
    public static native void sleep(long millis) throws InterruptedException;
    public static void sleep(long millis, int nanos) throws InterruptedException {...}
    public final synchronized void join(long millis) {...}
    public final synchronized void join(long millis, int nanos) {...}
    public final void join() {...}

    public static void dumpStack() {...}
    public StackTraceElement[] getStackTrace() {...}
    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {...}
    public native int countStackFrames();
    public final void checkAccess() {...}

    .
    .
    .

    public interface UncaughtExceptionHandler {...}
    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {...}
    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {...}
    public UncaughtExceptionHandler getUncaughtExceptionHandler() {...}
    public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {...}
}

The most important properties of a thread are:

When the JVM starts, there are four threads running (and two thread groups to house them):

initialthreads.png

Thread States

The six thread states:
NEW
The thread has not yet started.
RUNNABLE
The thread is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.
BLOCKED
The thread is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.
WAITING
The thread is waiting due to calling one of the following methods:
  • Object.wait with no timeout
  • Thread.join with no timeout
  • LockSupport.park
TIMED_WAITING
The thread is waiting due to calling one of the following methods with a specified positive waiting time:
  • Thread.sleep
  • Object.wait with timeout
  • Thread.join with timeout
  • LockSupport.parkNanos
  • LockSupport.parkUntil
TERMINATED
The thread has completed execution.

Exercise: Draw a state diagram for a Java thread, using the six states above. You'll have to do some research to get the transitions (and their triggers) just right.

Of interest:

Creating and Starting a Thread

Every thread has a runnable object that it runs. A runnable is anything implementing this interface:

package java.lang;
public interface Runnable {
    void run();
}

Usually the runnable is passed to the thread's constructor. To start the thread, call the thread's start method. Don't call the run() method directly! If you do, it will run on the caller's thread (just like any normal method), which likely isn't what you want. Calling Thread.start() is the only way to spawn a new thread.

class Worker implements Runnable {
    ...
    public void run() {...}
}

...
    Worker w = new Worker();
    Thread t = new Thread(w);
    t.start();

There's a cool shortcut you can use because Thread implements Runnable:

class Worker extends Thread {
    ...
    public void run() {...}
}

    Worker w = new Worker();
    w.start();

If you want to be really compact, subclass Thread with an anonymous class:

    Thread t = new Thread() {
        ...
        public void run() {...}
    };
    t.start();

or even

    (new Thread() {
        ...
        public void run() {...}
    }).start();
Exercise: What limitations does this last technique have?

But since Java only allows single inheritance, you can't use this shortcut if your runnable already extends another class. A common idiom is to stick a thread inside the runnable object:

class Worker extends Generator implements Runnable {
    ...
    private Thread thread;
    public void run() {...}
    public void start() {
        thread = new Thread(this);
        thread.start();
    }

Stopping a Thread

A thread stops running when

How do you forcibly stop a thread? Answer: periodically examine a flag.

class Worker extends Thread {
    private volatile boolean readyToStop = false;
    public void finish() {readyToStop = true;}
    public void run() {
        while (!readyToStop) {
            ...
        }
    }
    ...
}
class Worker implements Runnable {
    private volatile Thread thread = new Thread(this);
    public void finish() {thread = null;}
    public void run() {
        while (thread == currentThread()) {
            ...
        }
    }
    ...
}

Don't call Thread.stop()

Do not call the deprecated stop() method. It is unsafe. It causes the thread to abort no matter what it's doing, and it could be in the middle of executing a critical section with data in an inconsistent state. See the article explaining the deprecation of Thread.stop, Thread.suspend and Thread.resume.

Uncaught Exceptions

Normally you'd want to wrap the body of the run() method in a try-finally block to make sure you clean up in case an exception was thrown. If you wanted to react to an exception you'd need catch-clauses as well. All run() methods would have to be structured this way.

An alternative is to install an UncaughtExceptionHandler for a thread or thread group. Or set the application-wide default uncaught exception handler. This example should explain it all:

UncaughtExceptionDemo.java
/**
 * An application illustrating the use of uncaught exception handlers. Remember
 * if an uncaught exception is thrown in a thread, the system first tries the
 * thread's uncaught exception handler; if that is missing it tries the thread's
 * thread group's handler; if that fails it tries the default uncaught exception
 * handler.
 */
public class UncaughtExceptionDemo {

    private ThreadGroup group1 = new ThreadGroup("group1") {
        public void uncaughtException(Thread t, Throwable x) {
            System.out.println(t.getName() + " deferred to its group to " + "handle uncaught exception: " + x);
        }
    };

    private Thread thread1 = new Thread(group1, "thread1") {
        {
            setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
                public void uncaughtException(Thread t, Throwable x) {
                    System.out.println(t.getName() + " handled its own " + "uncaught exception: " + x);
                }
            });
        }

        public void run() {
            throw new RuntimeException();
        }
    };

    private Thread thread2 = new Thread(group1, "thread2") {
        public void run() {
            throw new RuntimeException();
        }
    };

    private Thread thread3 = new Thread("thread3") {
        public void run() {
            throw new RuntimeException();
        }
    };

    public static void main(String[] args) {
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            public void uncaughtException(Thread t, Throwable x) {
                System.out.println(t.getName() + " invoked the default " + "handler for uncaught exception: " + x);
            }
        });
        UncaughtExceptionDemo demo = new UncaughtExceptionDemo();
        demo.thread1.start();
        demo.thread2.start();
        demo.thread3.start();
    }
}

Output:

thread2 deferred to its group to handle uncaught exception: java.lang.RuntimeException
thread1 handled its own uncaught exception: java.lang.RuntimeException
thread3 invoked the default handler for uncaught exception: java.lang.RuntimeException

Synchronization

In general getting actions in a multithreaded program to happen in some correct order is hard because

The JLS formally specificies a memory model and defines kinds of actions (read, write, synchronization, external, and thread divergence) so as to formally define a orderings of actions that help (see Section 17.4 of the specification).

While there are many details, the most useful things to know are:

Java developers have a lot of choices for synchronizing:

There are also things that look like synchronization but are not: priorities, sleeping, yielding, and timers.

The synchronized Statement

Every object has a monitor which can be locked an unlocked. The monitor can only be owned by one thread at a time. If the monitor is owned by t1 and a different thread t2 wants it, t2 blocks. When the monitor gets unlocked, the threads blocked on the monitor compete for it and only one of them gets it.

The monitor for object o is only acquired by executing a synchronized statement on o:

    synchronized (o) {
        ...
    }

The lock is freed at the end of the statment (whether it completes normally or via an exception).

You can mark methods synchronized

class C {
    synchronized void p() {...}
    static synchronized void q() {...}
    ...
}

but this is just syntactic sugar for

class C {
    void p() {synchronized (this) {...}}
    static void q() {synchronized(C.class) {...}}
    ...
}

The synchronized statement is used to enforce mutual exclusion. When multiple threads access the same piece of data, it's imperative that one thread not see the data in an intermediate state. Example:

class PriorityQueue {
    // Implemented as a binary heap
    private Object[] data;
    private int size;
    ...
    public synchronized add(Object o) {
        if (size == data.length) {
            throw new HeapFullException();
        }
        data[size++] = o;
        siftUp();
    }
    public synchronized Object remove() {
        ...
    }
    public synchronized String toString() {
        ...
    }
}

If the methods add() and remove() are not synchronized several problems could occur.

Exercise: Show how leaving these methods unsynchronized can result in (1) the incorrect item being removed, and (2) toString() showing duplicates. (To do this exercise you need to know how binary heaps work.)

Note: In the above example all methods have to be synchronized. If add() is synchronized and remove() is not, they can still both be running at the same time!

Volatile Fields

You might be able to avoid locking the object and still have mutual exclusion in the case in which the shared data is a single field. This is because Java guarantees loading and storing of variables (except longs and doubles) are atomic — there's no "intermediate state" during a store nor can it be changed in the middle of a load. (Note only loads and stores are atomic, an expression like x++ is not.)

HOWEVER, threads can hold variables in registers. If a shared variable is in a register one thread won't be able to see another thread's change to it. The volatile keyword is there to prevent that. The Java Language Specification states that "A field may be declared volatile, in which case the Java memory model ensures that all threads see a consistent value for the variable."

One policy that an implementation may take is that for fields marked volatile,
  • All reads must come from main memory
  • All writes must go to main memory

A volatile field can let you avoid a synchronized statement and the associated lock contention. (This works for longs and doubles, too — marking them volatile not only ensures threads see consistent updates but it forces atomicity where none existed before: see the JLS, section 17.7.)

Exercise: What happens if you make a field both final and volatile? Why does this happen?

Explicit Locks

If your synchronization requirements are very complex, explicit locks might be more convenient. Read the Javadocs for the package java.util.concurrent.locks; they are extensive and quite decent.

lockuml.png

Basic Usage

Rule #1: unlock the lock in a finally block!

    Lock l = ...;
    l.lock();
    try {
        // access the resource protected by this lock
    } finally {
        l.unlock();
    }
    Lock l = ...;
    if (l.trylock()) {
       // Got it
       try {...} finally {l.unlock();}
    } else {
       // Didn't get it right away, do something else
       ...
    }
    Lock l = ...;
    if (l.trylock(3000, TimeUnit.MILLISECONDS)) {
       // Got it
       try {...} finally {l.unlock();}
    } else {
       // Didn't get it within 3 seconds, do something else
       ...
    }
Exercise: Give a usage pattern for lockInterruptibly();

The ReentrantLock class

The Java Core API provides one class for single-owner locks [Javadocs]:

package java.util.concurrent.locks;
public class ReentrantLock implements Lock, java.io.Serializable {
    public ReentrantLock() {...}
    public ReentrantLock(boolean fair) {...}
    public void lock() {...}
    public void lockInterruptibly() throws InterruptedException {...}
    public boolean tryLock() {...}
    public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {...}
    public void unlock() {...}
    public Condition newCondition() {...}
    public int getHoldCount() {...}
    public boolean isHeldByCurrentThread() {...}
    public boolean isLocked() {...}
    public final boolean isFair() {...}
    protected Thread getOwner() {...}
    public final boolean hasQueuedThreads() {...}
    public final boolean hasQueuedThread(Thread thread) {...}
    public final int getQueueLength() {...}
    protected Collection<Thread> getQueuedThreads() {...}
    public boolean hasWaiters(Condition condition) {...}
    public int getWaitQueueLength(Condition condition) {...}
    protected Collection<Thread> getWaitingThreads(Condition condition) {...}
    public String toString() {...}
}

In this class

ReadWrite Locks

A ReadWriteLock [Javadocs] contains a pair of locks: one exlusive write lock and one non-exclusive read lock.

package java.util.concurrent.locks;
public interface ReadWriteLock {
    Lock readLock();
    Lock writeLock();
}

Explicit vs. Implicit Locking

Implicit Locks Explicit Locks
  • Are acquired only via synchronized statements (or methods)
  • Can only be used lexically
  • Can only be acquired and released in a LIFO way
  • Prevents common mistakes like forgetting to unlock
  • Are always blocking (and not iterruptibly so)
  • Are always reentrant
  • Cannot queue waiters fairly
  • Are pretty limited and inflexible, but easy and safe
  • Very flexible
  • Can lock and unlock pretty much at any time (for example the lock and unlock calls can be in different methods)
  • Can be associated with multiple condition variables
  • Can be programmed to allow exlusive access to a shared resource or concurrent access to a shared resource
  • Can participate in hand-over-hand (chain) locking
  • Support non-blocking conditional acquisition
  • Support a time-out acquisition attempt
  • Support an interruptable acquisition attempt
  • Must be used responsibly
  • Can be made to be non-reentrant
  • Can be made fair
  • Can be made to support deadlock detection

Condition Synchronization

A common synchronization issue arises when you have to modify a shared resource only if some condition holds. But you need the object lock to combine the check and update. However if the condition does not hold you want to block until it does. But you can't wait for the condition while holding the lock, so there's some built-in support for all this.

There are ways to do this with both implicit and explicit locks

Object.wait and Object.notify

The most straightforward way to implement this in Java is to use the wait and notify methods of the class Object. Here's an implementation of a blocking queue:

public class BlockingQueue {
    private Object[] data;
    private int head = 0;
    private int tail = 0;
    private int count = 0;
    public Buffer(int capacity) {
        data = new Object[capacity];
    }
    public synchronized void add(Object item) throws InterruptedException {
        while (count == data.length) {wait();}
        data[tail] = item;
        tail = (tail + 1) % data.length;
        count++;
        notifyAll();
    }
    public synchronized Object remove() throws InterruptedException {
        while (count == 0) {wait();}
        Object item = data[head];
        head = (head + 1) % data.length;
        count--;
        notifyAll();
        return item;
    }
    public synchronized int getSize() {
        return count;
    }
}

See the JLS for the semantics of wait and notify, or see the Javadocs for class Object for a slightly less formal treatment. The high-level explanation is:

The Condition Interface

Condition objects [Javadocs] give wait and notify functionality to explicit locks the same way wait() and notify() work with implicit locks. This gives us a situation where the add threads and the remove threads are in separate wait sets!. Example:

 class BlockingQueue {
     private final Lock lock = new ReentrantLock();
     private final Condition notFull  = lock.newCondition();
     private final Condition notEmpty = lock.newCondition();
     private final Object[] data;
     private int head = 0;
     private int tail = 0;
     private int count = 0;

     public void add(Object x) throws InterruptedException {
         lock.lock();
         try {
             while (count == items.length) notFull.await();
             data[tail] = item;
             tail = (tail + 1) % data.length;
             count++;
             notEmpty.signal();
         } finally {
             lock.unlock();
         }
     }

     public Object remove() throws InterruptedException {
         lock.lock();
         try {
             while (count == 0) notEmpty.await();
             Object item = data[head];
             head = (head + 1) % data.length;
             count--;
             notFull.signal();
             return item;
         } finally {
             lock.unlock();
         }
     }
 }
 

Good to know

Synchronization Objects

There are some cool little things you can use in place of locks and conditions. Most are objects that hand out "permits" — a thread blocks until a permit is available.

CountDownLatch

Threads wait on a countdown latch until the count goes down to zero. Then they pass.

package java.util.concurrent;
public class CountDownLatch {
    public CountDownLatch(int count) {...}
    public void await() throws InterruptedException {...}
    public boolean await(long timeout, TimeUnit unit) throws InterruptedException {...}
    public void countDown() {...}
    public long getCount() {...} // just for debugging and testing
    public String toString() {...}
}

The details

For examples of use, see the Javadocs.

CyclicBarrier

A number of threads meet (block) at the barrier, and when the last thread in the party arrives, they are all released. The barrier object can be reused after the threads have been released.

package java.util.concurrent;
public class CyclicBarrier {
    public CyclicBarrier(int parties, Runnable barrierAction) {...}
    public CyclicBarrier(int parties) {...}
    public int getParties() {...}
    public int await() throws InterruptedException, BrokenBarrierException {...}
    public int await(long timeout, TimeUnit unit) throws InterruptedException,
        BrokenBarrierException, TimeoutException {...}
    public boolean isBroken() {...}
    public void reset() {...}
    public int getNumberWaiting() {...} // just for debugging
}

Notes

For examples of use, see the Javadocs.

Exchanger

An exchanger is used as a synchronization point at which two threads can exchange objects. Each thread presents some object on entry to the exchange method, and receives the object presented by the other thread on return.

package java.util.concurrent;
public class Exchanger<V> {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition taken = lock.newCondition();
    private V item;
    .
    .
    .
    public Exchanger() {...}
    public V exchange(V x) throws InterruptedException {...}
    public V exchange(V x, long timeout, TimeUnit unit)
        throws InterruptedException, TimeoutException {...}
}

Good to know

For examples of use, see the Javadocs.

Semaphore

A semaphore maintains a counter of available permits; threads can block on a semaphore until there's a permit available. There are ways to acquire conditionally, interruptibly, or subject to a time out.

package java.util.concurrent;
public class Semaphore implements java.io.Serializable {
    public Semaphore(int permits) {...}
    public Semaphore(int permits, boolean fair) {...}
    public void acquire() throws InterruptedException {...}
    public void acquireUninterruptibly() {...}
    public boolean tryAcquire() {...}
    public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException {...}
    public void release() {...}
    public void acquire(int permits) throws InterruptedException {...}
    public void acquireUninterruptibly(int permits) {...}
    public boolean tryAcquire(int permits) {...}
    public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
        throws InterruptedException {...}
    public void release(int permits) {...}
    public int availablePermits() {...}
    public int drainPermits() {...} // acquire and return them all, return num acquired
    protected void reducePermits(int reduction) {...} // this does not block
    public boolean isFair() {...}
    public final boolean hasQueuedThreads() {...} // don't rely on it
    public final int getQueueLength() {...} // just an estimate; don't rely on it
    protected Collection<Thread> getQueuedThreads() {...} // just an estimate; don't rely on it
    public String toString() {...}
}

Good to know:

For examples of use, see the Javadocs.

Atomic Classes

The package java.util.concurrent.atomic [Javadocs] has a bunch of classes to make accessing single variables thread-safe without using locks. (Native methods are used instead.)

The classes

Good to know

Interrupting

Thread t1 can call t2.interrupt() to interrupt t2 from blocking on something:

If t is blocking on... Then t.interrupt() ... and t's interrupt status gets set to...
Object.wait
Thread.join
Thread.sleep
completes the blocking call and makes t get an InterruptedException false
an I/O operation on an interruptable channel closes the channel and makes t get a ClosedByInterruptException true
a selector completes the call (just like wakeup) true
nothing does nothing true

Checking the interrupt status

public static boolean interrupted()
Returns whether the current thread's interrupt status is true, and clears the status too!
public boolean isInterrupted()
Returns whether the thread in question's interrupt status is true (without affecting the status at all)

Suspension

A thread can voluntarily

But what if we want one thread to force another thread to suspend execution?

First, don't use the suspend() method! It's deprecated. (Threads keep their monitor locks when they go to sleep and this is very deadlock prone — the thread that's supposed to call resume just might try to get that very same lock!) See the article explaining the deprecation of Thread.stop, Thread.suspend and Thread.resume.) If you want to forcibly suspend some other thread, write the other thread to periodically see if it should be suspended and voluntarily block on a condition until woken up.

class Worker implements Runnable {
    private volatile boolean shouldBeSuspended = false;

    public void run() {
        while (true) {
            ...
            try {
                if (shouldBeSuspended) {
                    synchronized (this) {
                        while (shouldBeSuspended) wait();
                    }
                }
            catch (InterruptedException ignored) {
            }
            ...
        }
    }

    public void suspend() {
        shouldBeSuspended = true;
    }

    public synchronized void resume() {
        shouldBeSuspended = false;
        notify();
    }

    ...
}

You can get some of this functionality with LockSupport.park and LockSupport.unpark [Javadocs].

public class LockSupport {
    private LockSupport() {} // Cannot be instantiated.
    public static void park() {...}
    public static void parkNanos(long nanos) {...}
    public static void parkUntil(long deadline) {...}
    public static void unpark(Thread thread) {...}
}

Good to know

The Javadocs have a good example of how to implement a FIFO Mutex with the LockSupport methods.

Thread Locals

You should read Brian Goetz's article on ThreadLocals. It's better than anything I could write.

Exercise: Do ThreadLocals buy you anything over just making objects local to each thread's runnable's run() method?

Threads and Collections

Most of the time when threads share data, they're not just sharing a single variable. And as you know, updating a collection is rarely an atomic operation. There's lots of potential for races; there's also the potential for writing inefficient code with too much locking.

Java has a relatively huge API for collections. To get started, see my notes on collections These notes feature links to Sun's documentation and tutorial articles. I've also included there a table of cocurrency properties for each of the collection classes.

A summary of important points

Threads and Graphics

Graphics-intensive code pretty much requires threading: GUI programs are event-driven, and event handling and painting need to happen on a separate thread from your computations lets your computations prevent repainting. Of course, this means if you run code on this thread, it better not take too long.

Rule 1: All operations on the GUI thread should be short.

The interesting thing, though, is that the GUI components in Java's Swing Library (e.g. buttons, sliders, progress bars, dialogs, windows, scrollpanes, etc.) are not threadsafe. Updates you make on a "worker thread" will conflict with those made on the "event handling thread." (It doesn't matter if you enclose your worker code in a synchronized block — the internal component management code in Swing won't care!) Therefore:

Rule 2: Operate on Swing components only on the GUI thread.

After all, that's the general way to deal with thread-unsafe objects.

Introduction to Swing

Wait! Don't know much about Swing, or about graphics in general? Check out

Looking at the Threads in a Swing Application

Here's a little application that shows what kind of operations are performed on which threads:

GUIThreadDemo.java
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.ImageObserver;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
 * A small application that shows which threads execute particular operations,
 * in particular:
 * <ul>
 * <li>plain operations on the main thread</li>
 * <li>mouse event handlers</li>
 * <li>image loading observing</li>
 * <li>operations passed to SwingUtilities.invokeLater</li>
 * <li>operations passed to an anonymous thread</li>
 * </ul>
 */
public class GUIThreadDemo {

    public static void main(String[] args) {
        JFrame frame = new JFrame("Click in the window to exit");
        frame.setSize(600, 240);
        frame.setVisible(true);

        // What thread handles mouse events?
        frame.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                System.out.println("MouseEvent handled in " + Thread.currentThread());
                System.exit(0);
            }
        });

        // What thread does main() run on?
        System.out.println("main() runs in " + Thread.currentThread());

        // What about anonymous threads?
        (new Thread() {
            public void run() {
                System.out.println("This thread is " + Thread.currentThread());
            }
        }).start();

        // What thread does invokeLater run on?
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                System.out.println("SwingUtilities.invokeLater() runs on " + Thread.currentThread());
            }
        });

        // What thread are images loaded on?
        Image image = Toolkit.getDefaultToolkit()
                .getImage(GUIThreadDemo.class.getClassLoader().getResource("face.gif"));
        frame.getContentPane().getGraphics().drawImage(image, 0, 0, new ImageObserver() {
            public boolean imageUpdate(Image i, int flags, int x, int y, int width, int height) {
                if ((flags & ALLBITS) != 0) {
                    System.out.println("Image loaded in " + Thread.currentThread());
                    return false;
                }
                return true;
            }
        });
    }
}

On my box it outputs

main() runs in Thread[main,5,main]
This thread is Thread[Thread-2,5,main]
SwingUtilities.invokeLater() runs on Thread[AWT-EventQueue-0,6,main]
Image loaded in Thread[Image Fetcher 0,3,main]
MouseEvent handled in Thread[AWT-EventQueue-0,6,main]

How to Screw Up

TODO - example of blocking the GUI thread for a long time. The idea is to have a frame with two buttons, a text area, and a message area. The buttons simulate a 30 second server request. One button does the request on the GUI thread to illustrate the event thread lock up. The other does the request on another thread showing that you can still type in the text area.

TODO (maybe) - example of a race condition when updating a Swing component on the worker thread

Thread-Related Methods in SwingUtilities

Of interest to thread-conscious Swing developers is the SwingUtilities class are:

    SwingUtilities.invokeLater
    SwingUtilities.invokeAndWait
    SwingUtilities.isEventDispathThread

All these methods do is call the same-named methods in EventQueue. The implementation of these methods are interesting:

package awt;
public class EventQueue {
    .
    .
    .
    public static void invokeLater(Runnable runnable) {
        Toolkit.getEventQueue().postEvent(
            new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
    }

    public static void invokeAndWait(Runnable runnable)
             throws InterruptedException, InvocationTargetException {

        if (EventQueue.isDispatchThread()) {
            throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
        }

        class AWTInvocationLock {}

        Object lock = new AWTInvocationLock();
        InvocationEvent event =
            new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock, true);

        synchronized (lock) {
            Toolkit.getEventQueue().postEvent(event);
            lock.wait();
        }

        Throwable eventThrowable = event.getThrowable();
        if (eventThrowable != null) {
            throw new InvocationTargetException(eventThrowable);
        }
    }

    public static boolean isDispatchThread() {
        EventQueue eq = Toolkit.getEventQueue();
        EventQueue next = eq.nextQueue;
        while (next != null) {
            eq = next;
            next = eq.nextQueue;
        }
        return (Thread.currentThread() == eq.dispatchThread);
    }
}

As you can probably imagine, the InvocationEvent looks like:

package java.awt.event;
public class InvocationEvent extends AWTEvent implements ActiveEvent {
    public InvocationEvent(Object source, Runnable runnable) {....}
    public InvocationEvent(Object source, Runnable runnable, Object notifier,
                           boolean catchThrowables) {....}
    public void dispatch() {
    if (catchExceptions) {
        try {
        runnable.run();
        }
        catch (Throwable t) {
                if (t instanceof Exception) {
                    exception = (Exception) t;
                }
                throwable = t;
        }
    }
    else {
        runnable.run();
    }

    if (notifier != null) {
        synchronized (notifier) {
        notifier.notifyAll();
        }
    }
    }
    public Exception getException() {...}
    public Throwable getThrowable() {...}
    .
    .
    .
}

SwingWorker

There's an interesting class called SwingWorker that isn't part of the Java Core API. Sun just posted its source to the web. It lets you execute a time-consuming task on a worker thread and after that worker is finished you can do a little something on the GUI thread:

import javax.swing.SwingUtilities;
public abstract class SwingWorker {
    private Object value;

    /**
     * Class to maintain reference to current worker thread
     * under separate synchronization control.
     */
    private static class ThreadVar {
        private Thread thread;
        ThreadVar(Thread t) { thread = t; }
        synchronized Thread get() { return thread; }
        synchronized void clear() { thread = null; }
    }

    private ThreadVar threadVar;

    protected synchronized Object getValue() {
        return value;
    }
    private synchronized void setValue(Object x) {
        value = x;
    }

    // Override construct() and perhaps finished() in your subclass
    public abstract Object construct();
    public void finished() {}

    public void interrupt() {
        Thread t = threadVar.get();
        if (t != null) {
            t.interrupt();
        }
        threadVar.clear();
    }

    /**
     * Return the value created by the construct method.
     * Returns null if either the constructing thread or the current
     * thread was interrupted before a value was produced.
     *
     * @return the value created by the construct method
     */
    public Object get() {
        while (true) {
            Thread t = threadVar.get();
            if (t == null) {
                return getValue();
            }
            try {
                t.join();
            }
            catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // propagate
                return null;
            }
        }
    }


    /**
     * Start a thread that will call the construct method
     * and then exit.
     */
    public SwingWorker() {
        final Runnable doFinished = new Runnable() {
           public void run() { finished(); }
        };

        Runnable doConstruct = new Runnable() {
            public void run() {
                try {
                    setValue(construct());
                }
                finally {
                    threadVar.clear();
                }

                SwingUtilities.invokeLater(doFinished);
            }
        };

        Thread t = new Thread(doConstruct);
        threadVar = new ThreadVar(t);
    }

    /**
     * Start the worker thread.
     */
    public void start() {
        Thread t = threadVar.get();
        if (t != null) {
            t.start();
        }
    }
}

To use

    private Action saveAction = new AbstractAction("Save") {
        public void actionPerformed(ActionEvent e) {
            final SwingWorker worker = new SwingWorker() {
                // define fields here if you need them

                public Object construct() {
                    // contact a server or do a serious calculation
                    // return something if necessary
                }

                public void finished() {
                    // Update GUI
                }
            };
            worker.start();
        }
    }

Threads and I/O

TODO

Scheduling

Threads are important (actually, required) when you need to run certain jobs at certain times, or periodically, or until certain times, etc.

Understand the difference between the different uses of scheduling:

Priority-Based Scheduling

Every Java thread has a priority between 0 and 10. The priority is initally that of the thread that created it. You can call setPriority() to change it; the JVM will never change it on its own.

The JVM uses a preemptive, priority-based scheduler. When it is time to pick a thread to run, the scheduler picks

the highest priority thread that is currently runnable

and

when a thread gets moved into the runnable state and the currently executing thread as strictly lower priority, the higher priority thread preempts the running thread

and

among threads of the same priority, round-robin scheduling is used
.

BUT these are only guidelines, or hints, provided to the operating systems. The operating system makes the ultimate scheduling choices. In other words, the priority within the JVM is not the same as the priority of the thread assigned by the operating system!! Don't even expect it to be. The O.S. can give boosts; the JVM will not. So you can never rely on priorites for synchronization, ordering of operations, or race condition prevention.

Scheduling Events

An example of how things might work:

priority.png

Things you might consider...

Generally you should not care about this stuff, but if you have a platform that you know is not timesliced and you have a CPU-intensive thread, you might want to give this thread a priority less than the GUI thread. Do you see why?

And in general, threads that block a lot should get a higher priority than those that are CPU-intensive. Do you see why?

Thread Pools

A thread pool is a fixed collection of threads that you submit tasks to. A thread in the pool generally wakes up to run a task, then goes back to idling.

By task we mean either a Runnable or a Callable

package java.lang;
public class Runnable {
    void run();
}
package java.util.concurrent;
public interface Callable<V> {
    V call() throws Exception;
}

What good are thread pools?

But don't use thread pools when

Executors

An executor is something that runs a task

package java.util.concurrent;
public interface Executor {
    void execute(Runnable command);
}

There's a simple executor interface, called an ExecutorService [Javadocs]:

package java.util.concurrent;
public interface ExecutorService extends Executor {
    void shutdown();
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;

    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future< submit(Runnable task);

    <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks)
        throws InterruptedException;
    <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, long timeout, TimeUnit unit)
        throws InterruptedException;
    <T> T invokeAny(Collection<Callable<T>> tasks)
        throws InterruptedException, ExecutionException;
    <T> T invokeAny(Collection<Callable<T>> tasks, long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

and an executor which extends the simple ExecutorService with the ability to schedule tasks [Javadocs]:

package java.util.concurrent;
public interface ScheduledExecutorService extends ExecutorService {
    ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
    <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
    ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
    ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
}

Here is a pretty cool example that uses a simple thread pool (not how the thread pool is returned from a static factory method in the Executors class). The example is very simple; it only calls execute, not submit, and cares not at all about what "results" the tasks are computing (there are none), nor does it care about termination.

ThreadPoolBouncer.java
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 * A simple Swing application that serves as a demostration of graphics and
 * thread pools. A user can launch bouncing balls by clicking on a button. Each
 * ball is run on a thread and these threads come from a fixed-size thread pool.
 * Each ball lives for a limited but not too short of a time, so repeatedly
 * clicking the launch button can cause the pool to fill up and require new
 * balls to wait.
 *
 * The main frame window includes a status line with information about the
 * application's state.
 */
public class ThreadPoolBouncer extends JFrame implements Runnable {
    private Random random = new Random();

    private static final int POOL_SIZE = 8;
    private JPanel canvas = new JPanel();
    private JLabel statusLabel = new JLabel();
    private int activeCount = 0;
    private int waitCount = 0;

    /**
     * A thread to do the rendering on, since we don't want to render on the user
     * interface thread.
     */
    private Thread renderThread = new Thread(this);

    /**
     * Stores all the ball tasks. Note balls are not threads -- they are runnables
     * which will be run on threads from a thread pool.
     */
    private List<Ball> balls = Collections.synchronizedList(new ArrayList<Ball>());

    private ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE);

    /**
     * An action to launch a new ball.
     */
    private Action launchAction = new AbstractAction("Launch") {
        public void actionPerformed(ActionEvent e) {
            Ball ball = new Ball();
            balls.add(ball);
            synchronized (this) {
                waitCount++;
                updateStatus();
            }
            pool.execute(ball);
        }
    };

    /**
     * Constructs and lays out the application frame.
     */
    public ThreadPoolBouncer() {
        JPanel statusPanel = new JPanel();
        statusPanel.add(new JButton(launchAction));
        statusPanel.add(statusLabel);
        getContentPane().add(statusPanel, BorderLayout.SOUTH);
        getContentPane().add(canvas, BorderLayout.CENTER);
        setResizable(false);
    }

    /**
     * Renders the canvas with all the balls. First it creates a back buffer and
     * graphics objects for the back buffer and the canvas. Then it loops around
     * drawing all the live balls to the back buffer then blitting the back buffer
     * to the canvas.
     */
    public void run() {
        Image buffer = createImage(canvas.getWidth(), canvas.getHeight());
        Graphics g = buffer.getGraphics();
        Graphics gc = canvas.getGraphics();
        while (true) {
            g.setColor(Color.white);
            g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            synchronized (balls) {
                for (Ball b : balls) {
                    b.draw(g);
                }
            }
            gc.drawImage(buffer, 0, 0, canvas);
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
            }
        }
    }

    private void updateStatus() {
        final String text;
        synchronized (this) {
            text = "Waiting: " + waitCount + " Active: " + activeCount;
        }
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                statusLabel.setText(text);
            }
        });
    }

    /**
     * Runs the demonstration as an application.
     */
    public static void main(String[] args) {
        ThreadPoolBouncer bouncer = new ThreadPoolBouncer();
        bouncer.setTitle("Bouncing Balls");
        bouncer.setSize(800, 600);
        bouncer.setVisible(true);
        bouncer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        bouncer.renderThread.setPriority(Thread.MAX_PRIORITY);
        bouncer.renderThread.start();
    }

    /**
     * A ball is something that bounces around on a JPanel. Balls are created with a
     * random color not too close to white, initially at a random position on the
     * canvas and oriented in an random direction (neither horizontal or vertical).
     */
    private class Ball implements Runnable {
        private Color color = new Color(random.nextInt(200), random.nextInt(200), random.nextInt(255));
        private int x = random.nextInt(getWidth());
        private int y = random.nextInt(getWidth());
        private int dx = 1 + random.nextInt(5);
        private int dy = 1 + random.nextInt(3);
        private static final int RADIUS = 10;

        /**
         * Draws the ball as a filled in circle.
         */
        public void draw(Graphics g) {
            g.setColor(color);
            g.fillOval(x, y, RADIUS, RADIUS);
        }

        /**
         * Updates the position of the ball, taking care of bounces.
         */
        protected void move() {
            x += dx;
            y += dy;
            if (x < 0) {
                // Bounce off left wall.
                x = 0;
                dx = -dx;
            }
            if (x + RADIUS >= canvas.getWidth()) {
                // Bounce off right wall.
                x = canvas.getWidth() - RADIUS;
                dx = -dx;
            }
            if (y < 0) {
                // Bounce off top wall.
                y = 0;
                dy = -dy;
            }
            if (y + RADIUS >= canvas.getHeight()) {
                // Bounce off bottom wall.
                y = canvas.getHeight() - RADIUS;
                dy = -dy;
            }
        }

        /**
         * A ball basically just moves 1000 times. After each position update, it sleeps
         * for 5 milliseconds.
         */
        public void run() {
            synchronized (this) {
                waitCount--;
                activeCount++;
                updateStatus();
            }
            for (int i = 1; i <= 1000; i++) {
                move();
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                }
            }
            balls.remove(this);
            synchronized (this) {
                activeCount--;
                updateStatus();
            }
        }
    }
}

Constructing an Executor Service

You will need to instantiate a concrete class to actually use a thread pool. The simple ThreadPoolExecutor implements the ExecutorService

TODO

The ScheduledThreadPoolExecutor extends the ScheduledExecutorService:

TODO

If you don't need sophisticated control over the thread pool, there are static factory methods in the utility class Executors you can use.

TODO

Submitting Tasks

TODO

Invoking Tasks

TODO

Monitoring Tasks

TODO - describe the Future interface and how it works

Scheduling Tasks

TODO

Shutdown and Termination

TODO

java.util.Timer

If you have very simple scheduling needs, you can use a simple timer in place of a scheduled thread pool executor. The Timer class in java.util looks like:

TODO

java.swing.Timer

The swing timer class is even simpler and less flexible than the util timer, but it's there to make it easy to execute actions on the GUI threads. Swing timers aren't very generic: they only support one "schedule".

TODO

Thread Groups

TODO