A thread can be in any one of four states:
New: The thread object has been created, but it hasn't been started yet, so it cannot run.
Runnable: This means that a thread can be run when the time-slicing mechanism has CPU cycles available for the thread. Thus, the thread might or might not be running at any moment, but there's nothing to prevent it from being run if the scheduler can arrange it; it's not dead or blocked.
Dead: The normal way for a thread to die is by returning from its run( ) method. Before it was deprecated in Java 2, you could also call stop( ), but this could easily put your program into an unstable state. There's also a destroy( ) method (which has never been implemented, and probably never will be, so it's effectively deprecated). You'll learn about an alternative way to code a stop( ) equivalent later in the chapter.
Blocked: The thread could be run, but there's something that prevents it. While a thread is in the blocked state, the scheduler will simply skip over it and not give it any CPU time. Until a thread reenters the runnable state, it won't perform any operations.
When a thread is blocked, there's some reason that it cannot continue running. A thread can become blocked for the following reasons:
You've put the thread to sleep by calling sleep(milliseconds), in which case it will not be run for the specified time.
You've suspended the execution of the thread with wait( ). It will not become runnable again until the thread gets the notify( ) or notifyAll( ) message. We'll examine these in the next section.
The thread is waiting for some I/O to complete.
The thread is trying to call a synchronized method on another object, and that object's lock is not available.
In old code, you may also see suspend( ) and resume( ) used to block and unblock threads, but these are deprecated in Java 2 (because they are deadlock-prone), and so will not be examined in this book.