一、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中线程状态的变化关系。后续我也会再补充一些案例,大家一起讨论。

三、项目案例

地址:https://gitee.com/CheonSeongIm/multi-thread-demo

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐