Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Now that you've seen how to give a thread something to do, let's review some details that were glossed over in the previous section. In particular, we look at how to create and start a thread, some of the special things it can do while it's running, and how to stop it.The following figure shows the states a thread can be in during its life and illustrates which method calls cause a transition to another state. This figure is not a complete finite state diagram but rather an overview of the more interesting and common facets of a thread's life. The remainder of this section uses the previously introduced
Clock
applet to discuss a thread's life cycle in terms of its state.Thread states.
The application in which an applet is running calls the applet'sstart
method when the user visits the applet's page. TheClock
applet creates aThread
,clockThread
, in itsstart
method with the code shown in boldface.After the statement has been executed,public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } }clockThread
is in theNew Thread
state. A thread in this state is merely an emptyThread
object; no system resources have been allocated for it yet. When a thread is in this state, you can only start the thread. Calling any method besidesstart
when a thread is in this state makes no sense and causes anIllegalThreadStateException
. In fact, the runtime system throws anIllegalThreadStateException
whenever a method is called on a thread and that thread's state does not allow for that method call.Note that the
Clock
instance is the first argument to the thread constructor. The first argument to this thread constructor must implement theRunnable
interface and becomes the thread's target. TheclockThread
gets itsrun
method from its targetRunnable
object in this case, theClock
instance. The second argument is just a name for the thread.
Now consider the next line of code inClock
'sstart
method, shown here in boldface.Thepublic void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } }start
method creates the system resources necessary to run the thread, schedules the thread to run, and calls the thread'srun
method.clockThread
'srun
method is defined in theClock
class.After the
start
method has returned, the thread is "running"; however, it's somewhat more complex than that. As the previous figure shows, a thread that has been started is in theRunnable
state. Many computers have a single processor, thus making it impossible to run all running threads at the same time. The Java runtime system must implement a scheduling scheme that shares the processor among all running threads; see the Thread Scheduling section for more information about scheduling. So, at any given time, a running thread may be waiting for its turn in the CPU.Here's another look at
Clock
'srun
method.public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { //The VM doesn't want us to sleep anymore, //so get back to work. } } }Clock
'srun
method loops while the conditionclockThread == myThread
istrue
. This exit condition is explained in more detail in the Stopping a Thread section. For now, however, know that it allows the thread, and thus the applet, to exit gracefully.Within the loop, the applet repaints itself and then tells the thread to sleep for one second (1,000 milliseconds). An applet's
repaint
method ultimately calls the applet'spaint
method, which does the actual update of the applet's display area. TheClock
paint
method gets the current time, formats it, and displays.public void paint(Graphics g) { //Get the time and convert it to a date. Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); //Format and display it. DateFormat dateFormatter = DateFormat.getTimeInstance(); g.drawString(dateFormatter.format(date), 5, 10); }
A thread enters Not Runnable state when one of the following events occurs:The
- Its
sleep
method is invoked.- The thread calls the
wait
method to wait for a specific condition to be satisifed.- The thread is blocking on I/O.
clockThread
in theClock
applet becomes Not Runnable when therun
method callssleep
on the current thread.During the second that thepublic void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { //The VM doesn't want us to sleep anymore, //so get back to work. } } }clockThread
is asleep, the thread does not run, even if the processor becomes available. After the second has elapsed, the thread becomes Runnable again; if the processor becomes available, the thread begins running again.For each entrance into the Not Runnable state, a specific and distinct exit returns the thread to the Runnable state. An exit works only for its corresponding entrance. For example, if a thread has been put to sleep, the specified number of milliseconds must elapse before the thread becomes Runnable again. The following list describes the exit for every entrance into the Not Runnable state:
- If a thread has been put to sleep, the specified number of milliseconds must elapse.
- If a thread is waiting for a condition, then another object must notify the waiting thread of a change in condition by calling
notify
ornotifyAll
; more information on this is available in the Synchronizing Threads section.- If a thread is blocked on I/O, the I/O must complete.
Although theThread
class does contain astop
method, this method is deprecated and should not be used to stop a thread because it is unsafe. Rather, a thread should arrange for its own death by having arun
method that terminates naturally. For example, thewhile
loop in thisrun
method is a finite loop: It will iterate 100 times and then exit.A thread with thispublic void run() { int i = 0; while (i < 100) { i++; System.out.format("i = %d%n", i); } }run
method dies naturally when the loop completes and therun
method exits.Let's look at how the
Clock
applet thread arranges for its own death. (You might want to use this technique with your applet threads.) Recall the code for theClock
'srun
method.The exit condition for thispublic void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { //The VM doesn't want us to sleep anymore, //so get back to work. } } }run
method is the exit condition for thewhile
loop because there is no code after thewhile
loop.This condition indicates that the loop will exit when the currently executing thread is not equal towhile (clockThread == myThread) {clockThread
. When would this ever be the case?When you leave the page, the application in which the applet is running calls the applet's
stop
method. This method then sets theclockThread
tonull
, thereby telling the main loop in therun
method to terminate.If you revisit the page, thepublic void stop() { //applet's stop method clockThread = null; }start
method is called again and the clock starts up again with a new thread. Even if you stop and start the applet faster than one iteration of the loop,clockThread
will be a different thread frommyThread
and the loop will still terminate.
A final word aboutThread
state: Release 5.0 introduced theThread.getState
method. When called on a thread, one of the followingThread.State
values is returned:The API for the
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
Thread
class also includes a method calledisAlive
. TheisAlive
method returnstrue
if the thread has been started and not stopped. If theisAlive
method returnsfalse
, you know that the thread either is aNew Thread
or isDead
. If theisAlive
method returnstrue
, you know that the thread is either in a Runnable or Not Runnable state.Prior to release 5.0, you couldn't differentiate between a
New Thread
or aDead
thread; nor could you differentiate between a Runnable thread and a Not Runnable thread.
Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.