目录
一、前言
本文介绍在之前的文章(Java学习第六十一部分——多线程-CSDN博客)中关于线程生命周期部分的拓展内容。
二、温故
[*] --> NEW
NEW --> RUNNABLE: start()
RUNNABLE --> RUNNING: 获取CPU时间片
RUNNING --> RUNNABLE: yield()/时间片用完
RUNNING --> BLOCKED: 等待锁
BLOCKED --> RUNNABLE: 获取锁
RUNNING --> WAITING: wait()/join()
WAITING --> RUNNABLE: notify()/notifyAll()
RUNNING --> TIMED_WAITING: sleep(ms)/wait(ms)
TIMED_WAITING --> RUNNABLE: 超时/唤醒
RUNNING --> TERMINATED: run()结束
三、知新
在 Java 中,线程的状态由 `java.lang.Thread.State` 枚举类定义,线程在其生命周期中会经历多种状态,以下介绍 Java 线程的六种状态。
1. NEW(新建状态)
描述:线程被创建但尚未启动时的状态。
示例:
Thread t = new Thread();
// 此时线程 t 的状态为 NEW
2. RUNNABLE(可运行状态)
描述:线程处于可运行状态,但不一定正在运行。线程可能正在运行,也可能正在等待 CPU 时间片(就绪状态)。这是线程的“活动”状态。
示例:
t.start();
// 调用 start() 后,线程进入 RUNNABLE 状态
3. BLOCKED(阻塞状态)
描述:线程被阻塞,等待获取一个监视器锁(即进入同步代码块或同步方法时,其他线程已经持有该锁)。
示例:
synchronized (this) {
// 如果其他线程已经持有 this 对象的锁,当前线程会进入 BLOCKED 状态
}
4. WAITING(等待状态)
描述:线程处于无限等待状态,不会自动唤醒,必须通过其他线程调用 `notify()` 或 `notifyAll()` 方法来唤醒。
示例:
synchronized (this) {
this.wait(); // 调用 wait() 后,线程进入 WAITING 状态
}
5. TIMED_WAITING(计时等待状态)
描述:线程处于有限时间的等待状态。在指定的时间内,线程不会被调度,时间结束后线程会自动唤醒。
示例:
synchronized (this) {
this.wait(1000); // 调用 wait(1000) 后,线程进入 TIMED_WAITING 状态,1000 毫秒后自动唤醒
}
// 或者
Thread.sleep(1000); // 调用 sleep(1000) 后,线程进入 TIMED_WAITING 状态,1000 毫秒后自动唤醒
6. TERMINATED(终止状态)
描述:线程已经执行完毕,无法再次启动。
示例:
t.start();
t.join(); // 等待线程 t 执行完毕
// 此时线程 t 的状态为 TERMINATED
7.获取线程状态
可以通过 `Thread.getState()` 方法获取线程的当前状态
Thread t = new Thread();
System.out.println(t.getState()); // 输出:NEW
t.start();
System.out.println(t.getState()); // 输出:RUNNABLE 或其他状态(取决于线程调度)
四、拓展
一点点小疑问
XXX:“停停停!我有个问题,为什么‘温故’中有七种状态,而‘知新’中只介绍了六种?RUNNING状态去哪里了?”
XXX:“在 Java 中,线程的状态中并没有一个单独的 RUNNING 状态,而是将线程正在运行的情况归类为 RUNNABLE 状态,所以在‘知新’中没有详细介绍它。为了更好解释线程的运行情况,我们可以将 RUNNING 状态视为 RUNNABLE 状态的一个子状态,用于描述线程正在实际执行代码的阶段。”
线程状态补充说明
RUNNING(运行状态)
描述:线程正在 CPU 上执行代码。这是 `RUNNABLE` 状态的一个子状态,表示线程不仅处于可运行状态,而且正在实际执行。
示例:
Thread t = new Thread(() -> {
System.out.println("线程正在运行");
});
t.start();
// 在 t.start() 后,线程可能会进入 RUNNING 状态(取决于线程调度器)
说明:
-
`RUNNABLE` 状态:线程处于可运行状态,但不一定正在运行。线程可能正在运行(即处于 `RUNNING` 状态),也可能正在等待 CPU 时间片(就绪状态)。
-
`RUNNING` 状态:线程正在实际执行代码。这是 `RUNNABLE` 状态的一个具体表现,表示线程已经获得了 CPU 时间片并正在运行。
获取线程状态:
虽然 Java 的 `Thread.State` 枚举中没有 `RUNNING` 状态,但可以通过逻辑判断来区分 `RUNNABLE` 状态中的 `RUNNING` 和 `RUNNABLE`(就绪)状态。例如:
Thread t = new Thread(() -> {
System.out.println("线程正在运行");
});
t.start();
// 判断线程是否处于 RUNNING 状态(逻辑判断)
if (t.getState() == Thread.State.RUNNABLE) {
System.out.println("线程可能正在运行或就绪");
}
总结:
-
`RUNNABLE` 状态:线程处于可运行状态,可能正在运行,也可能正在等待 CPU 时间片。
-
`RUNNING` 状态:线程正在实际执行代码,是 `RUNNABLE` 状态的一个子状态。
-
在实际开发中,`RUNNABLE` 状态已经足够描述线程的可运行情况,而 `RUNNING` 状态更多是一个逻辑上的概念,用于更细致地区分线程的运行情况。
五、总结
Java 中线程的状态主要包括新建(NEW
)、可运行(RUNNABLE
)、阻塞(BLOCKED
)、等待(WAITING
)、计时等待(TIMED_WAITING
)和终止(TERMINATED
),其中“可运行”状态涵盖了线程正在运行或就绪等待 CPU 的情况。