JAVA线程的状态(生命周期)及其变化关系
查看Thread.java中的源码可以看到,在java中定义了6种线程状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。)中,Thread.java类中状态枚举的摘录,上面的英文注释还是很有用的(学好英语是多么的重要……)。在操作系统层面和很多线程调度,一般以下分别对6种状态做逐个解释,并给出代码示例。但是请注意,以下给出的示例并不是
一、JAVA中线程的状态
查看Thread.java中的源码可以看到,在java中定义了6种线程状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。下面是github上OpenJDK源码(地址:https://github.com/openjdk/jdk)中,Thread.java类中状态枚举的摘录,上面的英文注释还是很有用的(学好英语是多么的重要……)。
/**
* A thread state. A thread can be in one of the following states:
* <ul>
* <li>{@link #NEW}<br>
* A thread that has not yet started is in this state.
* </li>
* <li>{@link #RUNNABLE}<br>
* A thread executing in the Java virtual machine is in this state.
* </li>
* <li>{@link #BLOCKED}<br>
* A thread that is blocked waiting for a monitor lock
* is in this state.
* </li>
* <li>{@link #WAITING}<br>
* A thread that is waiting indefinitely for another thread to
* perform a particular action is in this state.
* </li>
* <li>{@link #TIMED_WAITING}<br>
* A thread that is waiting for another thread to perform an action
* for up to a specified waiting time is in this state.
* </li>
* <li>{@link #TERMINATED}<br>
* A thread that has exited is in this state.
* </li>
* </ul>
*
* <p>
* 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
* @see #getState
*/
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.
*/
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
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called {@code Object.wait()}
* on an object is waiting for another thread to call
* {@code Object.notify()} or {@code Object.notifyAll()} on
* that object. A thread that has called {@code Thread.join()}
* is waiting for a specified thread to terminate.
*/
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:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
以下分别对6种状态做逐个解释,并给出代码示例。但是请注意,以下给出的示例并不是某个状态的固定场景,有可能仅仅是场景之一。
1、NEW(新建)
线程刚刚被创建,还没有开始运行,没有调用start方法。
示例:
ThreadStatusDemo1 runnable1 = new ThreadStatusDemo1();
Thread thread1 = new Thread(runnable1);
// 此时线程的状态为NEW
System.out.println("线程状态:" + thread1.getState());
2、RUNNABLE(可运行)
线程已经调用了start方法,正在JVM中运行,或准备运行(正在等待操作系统的某些资源)。但是在很多教程或者线程调度模型中,会把线程的可运行状态更细致的划分为:READY(就绪,代表着线程可运行,正在等待cpu调度开任务)和RUNNING(执行中,代表cpu调度了该线程的任务并正在执行)。所以,我们可以形象的把RUNNABLE状态理解为:排队+执行。
示例:
// 状态链路:NEW -> RUNNABLE -> TERMINATED
ThreadStatusDemo1 runnable1 = new ThreadStatusDemo1();
Thread thread1 = new Thread(runnable1);
// 此时线程的状态为NEW
System.out.println("线程状态:" + thread1.getState());
// 调用start方法后,线程开始运行,状态为RUNNABLE
thread1.start();
System.out.println("线程状态:" + thread1.getState());
3、BLOCKED(阻塞)
从该类的注释我们可以看到,阻塞状态是:线程正在等待获取一个对象监视器锁,从而进入同步代码块或者方法;或者在调用wait之后重新进入同步代码块或者方法。
示例:
public class MainDemo101 {
private static final Logger LOGGER = LoggerFactory.getLogger(MainDemo101.class);
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
LOGGER.info("主线程开始运行");
BlockRunnable1 blockRunnable1 = new BlockRunnable1();
BlockRunnable2 blockRunnable2 = new BlockRunnable2();
Thread t1 = new Thread(blockRunnable1);
Thread t2 = new Thread(blockRunnable2);
t1.start();
t2.start();
Thread.sleep(1000);
LOGGER.info("线程2的状态:" + t2.getState().toString());
}
static class BlockRunnable1 implements Runnable {
@Override
public void run() {
synchronized (lock) {
LOGGER.info("BlockRunnable1");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class BlockRunnable2 implements Runnable {
@Override
public void run() {
synchronized (lock) {
LOGGER.info("BlockRunnable2");
}
}
}
}
输出:
2025-11-20 09:07:29 [main] INFO c.s.d.m.thread.demo10.MainDemo101 - 主线程开始运行
2025-11-20 09:07:29 [Thread-0] INFO c.s.d.m.thread.demo10.MainDemo101 - BlockRunnable1
2025-11-20 09:07:30 [main] INFO c.s.d.m.thread.demo10.MainDemo101 - 线程2的状态:BLOCKED
2025-11-20 09:07:34 [Thread-1] INFO c.s.d.m.thread.demo10.MainDemo101 - BlockRunnable2
4、WAITING(等待)
线程处于无限期等待状态,需要其他线程显式唤醒。通过注释可以看出,可以通过三种方法进入等待状态:Object.wait、Thread.join、LockSupport.park。此时线程不会主动恢复执行,必须等待其他线程调用相应的唤醒方法。
示例:
public class MainDemo102 {
private static final Logger LOGGER = LoggerFactory.getLogger(MainDemo102.class);
private static final Object lock = new Object();
static void main() throws InterruptedException {
LOGGER.info("主线程开始运行");
WaitigRunnable waitigRunnable = new WaitigRunnable();
Thread t1 = new Thread(waitigRunnable);
t1.start();
Thread.sleep(1000);
LOGGER.info("t1线程的状态:" + t1.getState().toString());
synchronized (lock) {
LOGGER.info("主线程准备唤醒等待线程");
lock.notify();
}
Thread.sleep(1000);
LOGGER.info("t1线程的最终状态:" + t1.getState().toString());
}
static class WaitigRunnable implements Runnable {
@Override
public void run() {
LOGGER.info("等待线程开始运行");
synchronized (lock) {
LOGGER.info("等待线程进入等待状态");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("等待线程被唤醒");
}
}
}
}
输出:
2025-11-20 09:51:40 [main] INFO c.s.d.m.thread.demo10.MainDemo102 - 主线程开始运行
2025-11-20 09:51:40 [Thread-0] INFO c.s.d.m.thread.demo10.MainDemo102 - 等待线程开始运行
2025-11-20 09:51:40 [Thread-0] INFO c.s.d.m.thread.demo10.MainDemo102 - 等待线程进入等待状态
2025-11-20 09:51:41 [main] INFO c.s.d.m.thread.demo10.MainDemo102 - t1线程的状态:WAITING
2025-11-20 09:51:41 [main] INFO c.s.d.m.thread.demo10.MainDemo102 - 主线程准备唤醒等待线程
2025-11-20 09:51:41 [Thread-0] INFO c.s.d.m.thread.demo10.MainDemo102 - 等待线程被唤醒
2025-11-20 09:51:42 [main] INFO c.s.d.m.thread.demo10.MainDemo102 - t1线程的最终状态:TERMINATED
5、TIMED_WAITING(限时等待)
线程正在等待,但是只等待指定的时间,超时后自动恢复。和上一个状态有些类似,却别在于有等待时间。
示例:
public class MainDemo103 {
private static final Logger LOGGER = LoggerFactory.getLogger(MainDemo103.class);
public static void main(String[] args) throws InterruptedException {
TimedWaitigRunnable timedWaitigRunnable = new TimedWaitigRunnable();
Thread t1 = new Thread(timedWaitigRunnable);
t1.start();
Thread.sleep(1000);
LOGGER.info("t1线程的状态:" + t1.getState().toString());
Thread.sleep(3000);
LOGGER.info("t1线程的状态:" + t1.getState().toString());
}
static class TimedWaitigRunnable implements Runnable {
@Override
public void run() {
LOGGER.info("等待线程开始运行");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("等待线程运行完成");
}
}
}
输出:
2025-11-20 09:58:38 [Thread-0] INFO c.s.d.m.thread.demo10.MainDemo103 - 等待线程开始运行
2025-11-20 09:58:39 [main] INFO c.s.d.m.thread.demo10.MainDemo103 - t1线程的状态:TIMED_WAITING
2025-11-20 09:58:41 [Thread-0] INFO c.s.d.m.thread.demo10.MainDemo103 - 等待线程运行完成
2025-11-20 09:58:42 [main] INFO c.s.d.m.thread.demo10.MainDemo103 - t1线程的状态:TERMINATED
6、TERMINATED(终止)
线程已经执行完毕或者由于异常退出,生命周期结束。
示例:
// 状态链路:NEW -> RUNNABLE -> TERMINATED
ThreadStatusDemo1 runnable1 = new ThreadStatusDemo1();
Thread thread1 = new Thread(runnable1);
// 此时线程的状态为NEW
System.out.println("线程状态:" + thread1.getState());
// 调用start方法后,线程开始运行,状态为RUNNABLE
thread1.start();
System.out.println("线程状态:" + thread1.getState());
thread1.join();
// 调用join方法后,线程的状态为TERMINATED
System.out.println("线程状态:" + thread1.getState());
二、状态的变化关系
引用一张知名书籍《Java并发编程的艺术》中的图。大家只需要记住这个图的结构,把它想象成一个五角星,RUNNABLE在中间,其他五个分别在五个角,其中NEW和TERMINATED都是单向的,其他的是双向的。在后续的工作或学习中加以实战,即可理解java中线程状态的变化关系。后续我也会再补充一些案例,大家一起讨论。

三、项目案例
更多推荐


所有评论(0)