with an object to tell when the object is or is not being used.
Many real-world software problems can best be solved by using multiple threads of control. For example, an
interactive program that graphically displays data often needs to let users change display parameters in real
time. Interactive programs often obtain their best dynamic behavior by using threads. Single-threaded systems
usually provide an illusion of multiple threads either by using interrupts or by polling. Polling mixes the
display and user input parts of an application. In particular, the display code must be written so it will poll
often enough to respond to user input in fractions of a second. Display code either must ensure that display
operations take minimal time or must interrupt its own operations to poll. The resulting mixture of two
unrelated functional aspects of a program leads to complex and often unmaintainable code.
These kinds of problems are more easily solved in a multithreaded system. One thread of control updates the
display with current data, and another thread responds to user input. If user input is complexfor example,
filling out a form display code can run independently until it receives new data. In a polling model, either
display updates must pause for complex input or complicated handshaking must be used so that display
updates can continue while the user types data into the form. Such a model of shared control within a process
can be directly supported in a multithreaded system instead of being handcrafted for each new polling case.
This chapter describes the basic constructs, classes, and methods that control multithreading in the Java
programming language, but it cannot teach you effective multithreaded program design. The package
java.util.concurrent and its subpackages provide higher-level concurrency utilities to ease the task
of writing sophisticated multithreaded programs, but again the detailed use of such tools is beyond the scope
of this bookan overview is given in Section 25.9.1 on page 733. You can read Concurrent Programming in
Java™, Second Edition, a book in this series, to get advice on how to create well-designed multithreaded
programs. "Further Reading" on page 755 has other useful references to give you a background in thread and
synchronization design.
14.1. Creating Threads
To create a thread of control, you start by creating a THRead object:
Thread worker = new Thread();
After a THRead object is created, you can configure it and then run it. Configuring a thread involves setting
its initial priority, name, and so on. When the thread is ready to run, you invoke its start method. The
start method spawns a new thread of control based on the data in the Thread object, then returns. Now
the virtual machine invokes the new thread's run method, making the thread active. You can invoke start
only once for each threadinvoking it again results in an IllegalThreadStateException.
When a thread's run method returns, the thread has exited. You can request that a thread cease running by
invoking its interrupt methoda request a well-written thread will always respond to. While a thread is
running you can interact with it in other ways, as you shall soon see.
The standard implementation of Thread.run does nothing. To get a thread that does something you must
either extend Thread to provide a new run method or create a Runnable object and pass it to the thread's
constructor. We first discuss how to create new kinds of threads by extending THRead. We describe how to
use Runnable in the next section.
Here is a simple two-threaded program that prints the words "ping" and "PONG" at different rates:
public class PingPong extends Thread {