深入剖析 Java 线程的 BLOCKED 状态
在 Java 并发编程中,准确理解线程的生命周期状态是排查死锁、性能瓶颈的前提。在 Java 线程的 6 种状态(NEW, , , , , )中, 状态往往是容易被误解的一个。
许多开发者凭直觉认为:“只要线程被阻塞了,就是 状态”。这是一种极其普遍的错误认知。本文将详细梳理线程进入 状态的确切场景,并辟谣常见的误区。
一、 何时进入 状态?
在 Java 官方文档中深入剖析 Java 线程的 BLOCKED 状态, 状态的定义非常明确:线程正在等待获取一个内置的监视器锁以进入同步块/方法,或者在被 .wait() 唤醒后重新竞争锁失败时,线程处于此状态。
可以看出, 状态是 关键字的专属状态。具体触发场景有两个:
场景一:首次竞争内置锁失败
这是最常见的场景。当线程 A 已经持有了对象 obj 的监视器锁,正在执行 (obj) 代码块内部的代码。此时,线程 B 也尝试进入该同步块,由于锁被 A 占用java锁类型,线程 B 就会进入 状态,直到线程 A 释放锁。
场景二:被 wait() 唤醒后重入锁失败
这个场景经常被忽略,但在之前的讨论中我们已经明确它是真实的。
线程 A 在 代码块内部调用了 obj.wait()深入剖析 Java 线程的 BLOCKED 状态,此时线程 A 会释放锁,并进入 状态。随后,线程 B 获取到了锁,并调用了 obj.() 唤醒了线程 A。线程 A 被唤醒后,需要重新获取 obj 的锁才能从 wait() 方法返回并继续往下执行。如果此时线程 B 还没有执行完同步代码块(即尚未释放锁),线程 A 就会因为抢不到锁而进入 状态。二、 常见的四大误区
了解了触发场景后,我们来看看关于 状态最常见的四个误区。

误区一:等待 JUC 锁(如 )是 状态
事实:等待 等高级锁时,线程状态是 (或 ),而不是 。
这是面试和实际开发中最容易踩的坑。许多开发者认为“等锁”就是 ,但这仅适用于 。
为什么?
误区二:网络/磁盘 I/O 阻塞是 状态
事实:线程因为阻塞式 I/O(如 .read())而卡住时,其状态依然是 。
为什么?
在 Java 层面java锁类型, 状态不仅仅指“正在 CPU 上执行”,还包括“正在等待操作系统分配 CPU 时间片”以及“正在等待底层 I/O 资源”。
当线程执行阻塞式网络请求时,Java 虚拟机并不会将其标记为 。因为在 JVM 看来,线程并没有等待 Java 层面的锁,它只是把控制权交给了操作系统去等待网络数据。所以,当你用 查看一个卡在网络读取的线程时,你会看到它依然是 (通常伴随
.. 的堆栈)。
误区三:调用 .sleep() 会让线程进入 状态
事实:.sleep() 会让线程进入 状态。
为什么?

状态的唯一诱因是“等待 内置锁”。.sleep() 只是让当前线程主动让出 CPU 执行权,休眠一段时间,它与锁的竞争毫无关系。带时间的休眠属于 (限期等待)。
误区四:调用 .wait() 会进入 状态
事实:调用 .wait() 会进入 状态(或 )。
为什么?
虽然 wait() 必须在 块中调用,但线程一旦执行到 wait(),它就会立即释放持有的内置锁,并进入等待队列。既然锁被释放了,它就不存在“等待获取锁”的情况,因此绝对不是 。只有当它被 () 叫醒,重新去抢锁且抢不到的那一瞬间,才是 。
三、 总结与验证
为了方便记忆,我们可以用一个简单的公式来概括 Java 线程状态与锁/阻塞的关系:
你可以通过下面这段简单的代码,使用 或 IDEA 调试器亲自验证 JUC 锁的状态:
public class LockStateTest {
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
// 线程1:获取锁后一直休眠,不释放锁
new Thread(() -> {
lock.lock();
try { Thread.sleep(1000000); } catch (Exception e) {}
}, "Thread-Hold-Lock").start();
try { Thread.sleep(100); } catch (Exception e) {}
// 线程2:尝试获取锁,必然失败并被阻塞
new Thread(() -> {
lock.lock();
try {} finally { lock.unlock(); }
}, "Thread-Wait-Lock").start();
}
}
运行上述代码java锁类型,通过 抓取线程堆栈,你会发现 -Wait-Lock 的状态是:
java.lang..State: (),而不是 。
准确区分这些状态,在排查线上“线程假死”或“死锁”问题时能起到决定性作用,避免南辕北辙。
1. 本站所有资源来源于用户上传和网络,如有侵权请联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系站长处理!
6. 本站不售卖代码,资源标价只是站长收集整理的辛苦费!如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
7. 站长QQ号码 2205675299
资源库 - 资源分享下载网 » 深入剖析 Java 线程的 BLOCKED 状态
常见问题FAQ
- 关于资源售价和售后服务的说明?
- 代码有没有售后服务和技术支持?
- 有没有搭建服务?
- 链接地址失效了怎么办?
- 关于解压密码

