JVM 线程BLOCK阻塞实例

本文分析了Java应用中出现的线程阻塞问题,详细解释了一个线程因等待对象锁而进入阻塞状态的情况,并提供了具体的代码路径及锁定对象信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

"Thread-2" prio=10 tid=0x000000000d779000 nid=0x4268 waiting for monitor entry [0x00000000415b7000]
   java.lang.Thread.State: BLOCKED (on object monitor)
at sun.nio.ch.SelectorImpl.register(SelectorImpl.java:133)
- waiting to lock <0x000000075a6faf18> (a java.util.Collections$UnmodifiableSet)------------------------------------------------1处
at java.nio.channels.spi.AbstractSelectableChannel.register(AbstractSelectableChannel.java:209)
- locked <0x000000075bb739f0> (a java.lang.Object)
- locked <0x000000075bb73a00> (a java.lang.Object)
at com.tydic.ic.sub.MultiTCPClient$2.run(MultiTCPClient.java:253)
at java.lang.Thread.run(Thread.java:745)


   Locked ownable synchronizers:
- None


"Thread-1" prio=10 tid=0x00002aaac8184800 nid=0x4267 runnable [0x00000000401c8000]
   java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)
- locked <0x000000075a6faf98> (a sun.nio.ch.Util$2)                                                                     --------------------------------2处
- locked <0x000000075a6faf18> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000075a6fab60> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:102)
at ch.dermitza.securenio.AbstractSelector.run(AbstractSelector.java:379)

at java.lang.Thread.run(Thread.java:745)


根据jvm线程dump分析日志中,有   java.lang.Thread.State: BLOCKED (on object monitor)标识部分,为Jvm阻塞问题。其原因是”2处“锁住了0x000000075a6faf98对象。“1处”等待0x000000075a6faf98对象


### 进程和线程状态转换图 进程和线程的状态转换是操作系统中的核心概念之一,用于描述任务在其生命周期内的动态变化过程。以下是关于进程和线程状态转换的具体说明。 #### 状态定义与转换条件 1. **创建状态(New)** - 对于线程而言,在新创建了一个线程对象时,它处于新建状态[^1]。 2. **就绪状态(Runnable/Ready)** - 当线程对象通过 `start()` 方法被激活后,线程进入就绪状态。此时,线程已准备好运行,但尚未获得 CPU 资源[^1]。 - 就绪状态的线程位于操作系统的调度队列中,等待分配处理器时间片[^2]。 3. **运行状态(Running)** - 如果一个线程获得了 CPU 的使用权,那么它就会从就绪状态转变为运行状态,并开始执行其逻辑代码[^1]。 4. **阻塞状态(Blocked)** - 阻塞状态是指线程由于某些外部因素而暂停运行。具体来说,阻塞可以分为以下几种情况: - **等待阻塞**:当线程调用 `wait()` 方法时,JVM 会将其移至等待池中,直到某个特定事件发生才会唤醒该线程[^1][^2]。 - **同步阻塞**:如果多个线程尝试访问同一资源上的同步锁,但在某一时刻只有一个线程能够持有此锁,则其余竞争失败的线程会被置于等锁池中,直至它们成功获取锁为止[^2]。 - **其他阻塞**:除了上述两种情形外,还有可能是因为调用了诸如 `sleep(long millis)` 或者加入了另一个正在工作的线程(`join()`)等原因造成当前活动受到阻碍;另外还包括 I/O 请求未完成等情况下的延迟响应行为[^1]. 5. **终止状态(Terminated/Dead)** - 当线程完成了它的所有工作或者遇到了不可恢复错误从而退出 run 函数之后便进入了死亡阶段——这意味着这个实例已经结束了整个生命历程不能再继续下去了[^1]。 #### 状态转换图解析 虽然无法直接展示图形化的内容在此处,但是可以根据以上文字叙述构建出如下简单的流程关系: - 创建 -> 就绪 (启动 start()) - 就绪 <-> 运行 (取决于是否有可用 cpu 时间片) - 运行 -> 阻塞 (满足任意一种阻塞条件) - 阻塞 -> 就绪 (解除对应类型的阻塞原因) - 运行 / 阻塞 -> 终止 (正常结束或异常中断) 每一步骤之间的箭头表示可能发生的方向改变以及相应的触发机制是什么样的动作引起的转变。 ```plaintext +-------------------+ | Created/New | +--------+---------+ v +------------+-------------+ | Ready | +----------->|<-----------+ ^ ^ Run Block (Running) | v Terminated/Dead ``` 请注意实际应用当中可能会更加复杂些因为存在更多细节考量比如优先级调整等因素影响最终表现形式如何呈现出来。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值