A thread is always in one of the following six states:
All these states of a thread are JVM states.
When a thread is created and its start() method is not yet called, it is in the new state.
Thread t = new MyThreadClass(); // t is in the new state
A thread that is ready to run or running is in the runnable state.
A thread is in a blocked state if it is trying to enter or re-enter a synchronized method or block but the monitor is being used by another thread.
A thread may place itself in a waiting state by calling the methods listed in the following table.
Method | Description |
---|---|
wait() | from Object class. |
join() | from the Thread class. |
park() | from the java.util.concurrent.locks.LockSupport class. A thread that calls this method may wait until a permit is available by calling the unpark() method on a thread. |
A thread may place itself in a timed-waiting state by calling methods listed in the following table.
Method | Description |
---|---|
sleep() | from the Thread class. |
wait (long millis) wait(long millis, int nanos) | from the Object class. |
join(long millis) join(long millis, int nanos) | from the Thread class. |
parkNanos (long nanos) parkNanos (Object blocker, long nanos) | from LockSupport class, which is in the java.util.concurrent.locks package. |
parkUntil (long deadline) parkUntil (Object blocker, long nanos) | from the LockSupport class, which is in the java.util.concurrent.locks package. |
A thread that has completed its execution is in the terminated state.
A terminated thread cannot transition to any other state.
We can use the isAlive() method of a thread after it has been started to know if it is alive or terminated.
We can use the getState() method from the Thread class to get the state of a thread at any time.
This method returns one of the constants of the Thread.State enum type.
The following code demonstrate the transition of a thread from one state to another.
class ThreadState extends Thread { private boolean keepRunning = true; private boolean wait = false; private Object syncObject = null; //ww w .ja v a2 s . c o m public ThreadState(Object syncObject) { this.syncObject = syncObject; } public void run() { while (keepRunning) { synchronized (syncObject) { if (wait) { try { syncObject.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public void setKeepRunning(boolean keepRunning) { this.keepRunning = keepRunning; } public void setWait(boolean wait) { this.wait = wait; } } public class Main { public static void main(String[] args) throws InterruptedException { Object syncObject = new Object(); ThreadState ts = new ThreadState(syncObject); System.out.println("Before start()-ts.isAlive():" + ts.isAlive()); System.out.println("#1:" + ts.getState()); ts.start(); System.out.println("After start()-ts.isAlive():" + ts.isAlive()); System.out.println("#2:" + ts.getState()); ts.setWait(true); Thread.currentThread().sleep(100); synchronized (syncObject) { System.out.println("#3:" + ts.getState()); ts.setWait(false); syncObject.notifyAll(); } Thread.currentThread().sleep(2000); System.out.println("#4:" + ts.getState()); ts.setKeepRunning(false); Thread.currentThread().sleep(2000); System.out.println("#5:" + ts.getState()); System.out.println("At the end. ts.isAlive():" + ts.isAlive()); } }
The code above generates the following result.