线程转储分析:异常行为——等待线程问题排查
我来帮你分析这两个问题,结合你提供的WebSphere线程转储片段一一解答:
首先先把你给出的线程转储片段整理如下:
2LKMONINUSE sys_mon_t:0x00007FC510A24818 infl_mon_t: 0x00007FC510A24890: 3LKMONOBJECT java/lang/Object@0x00000001C4D927B8: <unowned> 3LKNOTIFYQ Waiting to be notified: 3LKWAITNOTIFY "ORB.thread.pool : 2" (J9VMThread:0x000000000BBDD200) 3LKWAITNOTIFY "ORB.thread.pool : 3" (J9VMThread:0x000000000CB22200) 3LKWAITNOTIFY "ORB.thread.pool : 4" (J9VMThread:0x000000000C9A1800) 3LKWAITNOTIFY "ORB.thread.pool : 6" (J9VMThread:0x000000000C624C00) 3LKWAITNOTIFY "ORB.thread.pool : 9" (J9VMThread:0x000000000CE5F400) 3LKWAITNOTIFY "WebContainer : 13" (J9VMThread:0x000000000CD20000) 3LKWAITNOTIFY "ORB.thread.pool : 11" (J9VMThread:0x000000000C61AA00) 3LKWAITNOTIFY "ORB.thread.pool : 23" (J9VMThread:0x000000000CA0C200) 3LKWAITNOTIFY "ORB.thread.pool : 25" (J9VMThread:0x000000000C216D00) 3LKWAITNOTIFY "ORB.thread.pool : 26" (J9VMThread:0x000000000CA85000) 3LKWAITNOTIFY "ORB.thread.pool : 27" (J9VMThread:0x000000000C4E8500)
a) 为何线程会等待未被持有的对象?
这种现象和Java的等待/通知机制的特性紧密相关,主要有几个常见的诱因:
虚假唤醒(Spurious Wakeups):Java规范明确允许
Object.wait()在没有收到notify()或notifyAll()信号的情况下被“虚假”唤醒。如果你的代码没有用循环(while)检查等待条件(而是用单次if判断),线程被虚假唤醒后会重新调用wait(),而wait()会自动释放对象锁,所以此时线程转储会显示对象处于<unowned>状态,但线程仍留在等待队列中。这是最常见的原因,一定要养成用while(等待条件)包裹wait()的习惯。通知丢失或未触发:原本持有该对象锁的线程可能在释放锁前没有调用
notify()/notifyAll()——比如线程因异常提前退出、业务逻辑分支遗漏了通知代码,或者只调用了notify()(只会随机唤醒一个等待线程),导致其他线程仍滞留在等待队列中。此时锁已经被释放,但等待的线程没有收到唤醒信号,就会持续处于等待状态。线程转储的时序巧合:在抓取线程转储的那一刻,刚好持有锁的线程刚释放锁,还没有任何线程获取到这个锁,而等待队列里的线程还没被唤醒或重新竞争锁。如果只是偶尔出现这种情况可能是瞬时状态,但如果频繁出现,还是要重点排查代码的等待/通知逻辑是否存在漏洞。
b) WebContainer线程与ORB.thread.pool线程有何区别?
这两个线程池在WebSphere中负责完全不同的工作负载,是两个独立的处理通道:
WebContainer线程:专门处理HTTP请求的线程池,属于WebSphere的Web容器核心组件。这些线程会接收客户端发来的HTTP请求,解析请求报文,调用Servlet、JSP、Spring MVC等Web组件处理业务逻辑,最终生成HTTP响应返回给客户端。线程池的配置大小直接决定了Web应用处理并发HTTP请求的能力,相关配置可以在WebSphere控制台的“Web容器”设置中调整。
ORB.thread.pool线程:ORB(Object Request Broker)是CORBA规范的实现,这个线程池专门处理分布式对象调用场景——比如EJB远程调用、RMI(远程方法调用)、跨应用服务器的组件通信,以及部分JMS相关的远程交互。简单来说,只要涉及到跨JVM的对象方法调用,大概率会用到ORB线程池,和Web容器的HTTP请求处理是完全隔离的。
内容的提问来源于stack exchange,提问作者pdg

