CS 136 - Lecture 35

  1. Threads
    1. Thread life-cycle
    2. Monitors and synchronized methods


Java supports programming concurrent processes with threads. Several threads (processes) can be running on computer systems. If the system has only a single processor then the threads take turns running, with one of the highest priority threads always running. If there are the same number of processors as threads then each can be assigned to a single processor. In general, though, there are more processes active than there are processors.

Your java programs always have a number of threads going concurrently. For example, there is a thread for your main program, and another thread for the garbage collector. Other threads may be taking care of operating systems needs, graphics, etc.

New threads of execution can be created by defining a subclass of the class Thread and overriding the run method or by declaring a class to implement the Runnable interface. We'll focus here on defining a subclass of Thread.

Not surprisingly, Thread implements Runnable.

Thread life-cycle

The life-cycle of a thread is as follows: When a thread is created it is in the "born" state. Nothing happens until the thread's "start" method is called. It then enters the "ready" state, which means it is waiting to be assigned to a processor. When it becomes one of the highest priority threads which is ready, it can be "dispatched" or assigned to a processor.

It then generally runs (by executing the run method) until it is swapped out for another thread (going back to the ready state) or until one of the following happens:

Can ask thread if it is still alive with isAlive() method.

It is hard to suspend a thread if it is busy. As a result, often have a method that sets a flag that can then be checked each time through the loop to see if want to suspend. The thread can then suspend itself, though it will be "resumed" from outside. (A good implementation of the StopWatch -- to be done in lab today -- might proceed in this way.)

Monitors and synchronized methods

More complicated if multiple threads need to access the same data.

Can set up what is often called a monitor: Data structure which only allows access by one thread at a time.

Can declare methods in a class to be synchronized. Restricts so only one of the synchronized methods can be active at a time. (Ordinarily, several methods of the object may be executing at the same time!)

When a synchronized method is running, a "lock" is established on the synchronized methods, so that none can be executed until the lock is released by the executing thread.

Use pair of methods wait and notify when must wait on a condition. wait releases lock and places thread on a queue waiting to be notified that condition might have changed.

wait and notify can only be invoked from within synchronized methods (or methods called from within synchronized methods).

Use notifyAll if not sure which object is first in queue.

See code for circular buffer in Buffer folder in the Class examples on Cider Press.