前言
很多文章说Java线程有五种状态:NEW(新建)、RUNNABLE(就绪)、RUNNING(运行)、BLOCKED(阻塞)、DEAD(死亡),而阻塞又分为等待阻塞、同步阻塞、其它阻塞。
很遗憾这种说法是错误的,这五种状态确实早期的进程状态,也就是单线程进程的状态。
线程状态
Java线程到底有几种状态,其实只要打开一下JDK源码,看一下java.lang.Thread
类就知道了,java.lang.Thread
定义了一个内部枚举java.lang.Thread.State
,部分源码如下:
/**
* A thread can be in only one state at a given point in time.
* These states are virtual machine states which do not reflect
* any operating system thread states.
* 一个线程在特定的时刻,只能有一个状态。
* 这些状态是虚拟机的状态,不能反映任何操作系统的线程状态
* @since 1.5
*/
public enum State {
/**
* Thread state for a thread which has not yet started.
* 线程未开始的状态
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
* 可运行的线程状态,此状态的线程正在JVM中运行,
* 但也有可能在等待操作系统的其他资源,例如处理器
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* 阻塞状态的线程在等待一个监视器锁去进入同步代码块/方法,
* 或者调用后重新进入同步代码块/方法
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the following methods:
* Object.wait()
* Thread.join()
* LockSupport.park()
* A thread in the waiting state is waiting for another thread to
* perform a particular action.
* 由于调用了Object.wait()、Thread.join()、LockSupport.park()其中一个方法,线程进入等待状态
* 处于等待状态的线程,正在在等待另一个线程执行特定的操作
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* Thread.sleep()
* Object.wait()
* LockSupport.parkNanos()
* LockSupport.parkUntil()
* 有指定等待时间的线程等待状态
* 由于调用了Thread.sleep(long)、Object.wait(long)、Thread.join(long)、
* LockSupport.parkNanos(long)、LockSupport.parkUntil(long)其中一个方法并传入了正(数)时间参数,
* 线程处于有时间限制的等待状态
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
* 线程已经执行完成,处于终止状态
*/
TERMINATED;
}
根据上述代码,可以知道Java线程有六个状态:NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(指定时间的等待)、TERMINATED(终止),线程之间的转换关系如下:
值得注意的是,Java线程是不区分Ready(就绪)和Running(运行)的,它们都是Runnable状态,我把他们画出来,是为了强调,也便于理解。
实例
- 线程状态:NEW -> RUNNABLE -> TERMINATED
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("执行run(),线程状态:" + Thread.currentThread().getState().toString());
}
});
System.out.println("未调用start(),线程状态:" + thread.getState().toString());
thread.start();
// 睡眠1秒,让thread执行完成
Thread.sleep(1000);
System.out.println("线程执行完成,线程状态:" + thread.getState().toString());
}
- 执行结果
未调用start(),线程状态:NEW
执行run(),线程状态:RUNNABLE
线程执行完成,线程状态:TERMINATED
- 线程状态:NEW -> RUNNABLE -> TIMED_WAITING -> RUNNABLE -> TERMINATED
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("执行run(),thread线程状态:" + Thread.currentThread().getState().toString());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sleep结束,thread线程状态:" + Thread.currentThread().getState().toString());
}
});
System.out.println("未调用start(),thread线程状态:" + thread.getState().toString());
thread.start();
// 睡眠200毫秒,让thread被调度起来,进入sleep
Thread.sleep(200);
System.out.println("线程sleep,thread线程状态:" + thread.getState().toString());
// 睡眠2秒,让thread执行完成
Thread.sleep(2000);
System.out.println("线程执行完成,thread线程状态:" + thread.getState().toString());
}
- 执行结果
未调用start(),thread线程状态:NEW
执行run(),thread线程状态:RUNNABLE
线程sleep,thread线程状态:TIMED_WAITING
sleep结束,thread线程状态:RUNNABLE
线程执行完成,thread线程状态:TERMINATED
- 线程状态:NEW -> RUNNABLE -> BLOCKED -> RUNNABLE -> TERMINATED
private static Object lock = new Object();
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("执行run(),thread线程状态:" + Thread.currentThread().getState().toString());
synchronized(lock) {
}
System.out.println("synchronized结束,thread线程状态:" + Thread.currentThread().getState().toString());
}
});
System.out.println("未调用start(),thread线程状态:" + thread.getState().toString());
synchronized(lock) {
thread.start();
Thread.sleep(200);
System.out.println("线程synchronized,thread线程状态:" + thread.getState().toString());
}
// 睡眠2秒,让thread执行完成
Thread.sleep(2000);
System.out.println("线程执行完成,thread线程状态:" + thread.getState().toString());
}
- 执行结果
未调用start(),thread线程状态:NEW
执行run(),thread线程状态:RUNNABLE
线程synchronized,thread线程状态:BLOCKED
synchronized结束,thread线程状态:RUNNABLE
线程执行完成,thread线程状态:TERMINATED
总结
以上便是Java线程的六种状态,及其切换。