4.2 Thread States
In this lesson we investigate the different states in which a thread can exist, and identify ways in which a thread can transition from one state to another.
Lets take a look at the points outlined at the Oracle Website for this part of the certification.
- Section 4: Concurrency
- Recognize the states in which a thread can exist, and identify ways in which a thread can transition from one state to another.
Different Thread States
Before we look at some of the methods of the
Thread class that alter state, it's worth spending a little time talking about the differing states a thread can exist in and how a
thread can transition between the varying states. To make understanding easier we will use a slideshow as we go through the life of a thread; just press the button below to step through each slide.
In this slide we have created a new
Thread object, which is just like any other object.
In this slide we have called the
start() method on this
Thread object and the thread has now transitioned to a runnable thread of execution.
In this slide the thread scheduler has selected this thread to run and the
run() method of this thread starts. The thread may return to a runnable state via the thread scheduler or through program code.
In this slide we are showing a blocked state which the thread may enter for any number of reasons. Eventually a blocked thread will return to a runnable state. A thread may just run to completion without ever being blocked and then die.
In this slide the
run() method of this thread has ended or an exception has propogated beyond the
run() method and the thread is dead.
Interrupting A Thread
The user threads we create don't die with the
main() method and even daemon threads continue processing until their
run() method ends. The overridden
run() methods in our lesson examples showed this by displaying thread output after the
main() method ended. We can interrupt a thread using the
interrupt() method doesn't actually stop a thread from running, but sets a flag in the thread that indicates that an interrupt has been requested. The flag must be checked
run() method for its effect to have any impact.
See the interrupt() method for an example, where we use the
sleep() method, in which we have to specify a
that checks to see if this thread has been interrupted and then throws the
InterruptedException for this thread.
static yield() method puts the currently running thread back to a runnable state to allow other threads of the same priority a chance to run. Although this sounds
a great way to use thread prioritisation and allow equal usage of the CPU in reality there is no guarantee that this will actually happen. What we can guarantee is that the
puts the currently running thread back to a runnable state. After this happens which thread gets chosen by the scheduler is out of our hands and it is very possible that the
yielding thread is selected again and goes straight back to executing. Lets have a look at how we can use the
See the yield() method for an example.
We have limited control over the order in which threads are run, but we do have some control. We can cease execution of a thread for a specified amount of time using the
sleep() method. We
can also use the
yield() method, to cease execution of a thread up to a specified amount of time and there are also options to prioritize threads as discussed in the
Concurrency - Thread Priorities lesson and how to lock threads as discussed in the Concurrency - Synchronization lesson.
There is another option available to us, the
join() method of the
Thread class which allows us to connect the current thread to a named thread, which is very handy
when we want to guarantee that one thread finishes before another.
See the join() method for an example, where we connect the current thread to a named thread.