Deitel & Associates, Inc. Logo

Back to
digg.png delicious.png blinkit.png furl.png
Java How to Program, 6/e

© 2005
pages: 1576
Buy the Book!
Amazon logo
InformIT logo

This four-part tutorial introduces multithreading in Java 5.0. You'll learn about the new thread-state model and the priority-based thread scheduler. We'll demonstrate how to create and execute threads by using the new classes Executors and ExecutorService from the java.util.concurrent package. You'll also learn how to create thread pools, which enable threads to be reused after they complete their tasks. This tutorial is intended for students who are already familiar with Java and for Java developers.

[Note: This series of four tutorials (Part 1, Part 2, Part 3, Part 4) is an excerpt (Sections 23.1-23.4) of Chapter 23, Multithreading, from our textbook Java How to Program, 6/e. These tutorials may refer to other chapters or sections of the book that are not included here. Permission Information: Deitel, Harvey M. and Paul J., JAVA HOW TO PROGRAM, ©2005, pp.1053-1058. Electronically reproduced by permission of Pearson Education, Inc., Upper Saddle River, New Jersey.]

23.2 Thread States: Life Cycle of a Thread

At any time, a thread is said to be in one of several thread states that are illustrated in the UML state diagram in Fig. 23.1. A few of the terms in the diagram are defined in later sections. Fig. 23.1 Thread life-cycle UML state diagram.

figure 23.1

A new thread begins its life cycle in the new state. It remains in this state until the program starts the thread, which places the thread in the runnable state. A thread in this state is considered to be executing its task.

Sometimes a thread transitions to the waiting state while the thread waits for another thread to perform a task. Once in this state, a thread transitions back to the runnable state only when another thread signals the waiting thread to continue executing.

A runnable thread can enter the timed waiting state for a specified interval of time. A thread in this state transitions back to the runnable state when that time interval expires or when the event it is waiting for occurs. Timed waiting threads cannot use a processor, even if one is available. A thread can transition to the timed waiting state if it provides an optional wait interval when it is waiting for another thread to perform a task. Such a thread will return to the runnable state when it is signaled by another thread or when the timed interval expires—whichever comes first. Another way to place a thread in the timed waiting state is to put the thread to sleep. A sleeping thread remains in the timed waiting state for a designated period of time (called a sleep interval) at which point it returns to the runnable state. Threads sleep when they momentarily do not have work to perform. For example, a word processor may contain a thread that periodically writes a copy of the current document to disk for recovery purposes. If the thread did not sleep between successive backups, it would require a loop in which it continually tests whether it should write a copy of the document to disk. This loop would consume processor time without performing productive work, thus reducing system performance. In this case, it is more efficient for the thread to specify a sleep interval (equal to the period between successive backups) and enter the timed waiting state. This thread is returned to the runnable state when its sleep interval expires, at which point it writes a copy of the document to disk and reenters the timed waiting state.

A runnable thread enters the terminated state when it completes its task or otherwise terminates (perhaps due to an error condition). In the UML state diagram in Fig. 23.1, the terminated state is followed by the UML final state (the bull’s-eye symbol) to indicate the end of the state transitions.

At the operating-system level, Java’s runnable state actually encompasses two separate states (Fig. 23.2). The operating system hides these two states from the Java Virtual Machine (JVM), which only sees the runnable state. When a thread first transitions to the runnable state from the new state, the thread is in the ready state. A ready thread enters the running state (i.e., begins executing) when the operating system assigns the thread to a processor—also known as dispatching the thread. In most operating systems, each thread is given a small amount of processor time—called a quantum or timeslice—with which to perform its task. When the thread’s quantum expires, the thread returns to the ready state and the operating system assigns another thread to the processor (see Section 23.3). Transitions between these states are handled solely by the operating system. The JVM does not “see” these two states—it simply views a thread as being in the runnable state and leaves it up to the operating system to transition threads between the ready and running states. The process that an operating system uses to decide which thread to dispatch is known as thread scheduling and is dependent on thread priorities (discussed in the next section). Fig. 23.2 Operating system’s internal view of Java’s runnable state.

figure 23.2

Page 1 | 2 | 3 | 4

Tutorial Index