threadinfo.getwaitingcount() 返回当前线程在指定monitor上处于waiting状态的线程数,仅统计已调用object.wait()、等待同一锁对象且未被唤醒的线程;需通过getthreadinfo(threadid, true)获取含锁信息的threadinfo,否则返回-1。

ThreadInfo.getWaitingCount() 是 Java 中 java.lang.management.ThreadInfo 类提供的一个方法,用于**获取当前线程在指定对象监视器(monitor)上处于 WAITING 状态的线程数量**。它反映的是调用 Object.wait() 后、尚未被 notify() 或 notifyAll() 唤醒的线程数。
这个值到底统计哪些线程?
该方法只统计满足以下全部条件的线程:
- 已执行过
object.wait()(即进入 WAITING 状态); - 等待的目标是当前
ThreadInfo所关联的锁对象(即通过ThreadMXBean.getThreadInfo(long, boolean, boolean)开启了“lockedMonitorInfo”选项获取到的ThreadInfo); - 尚未被
notify()/notifyAll()唤醒,也未因超时或虚假唤醒而返回。
注意:它不包括 TIMED_WAITING 状态的线程(如 wait(1000) 超时前的线程),也不包括阻塞在 synchronized 进入阶段的线程(那是 getBlockedCount() 的职责)。
怎么正确获取 waitingCount?
直接调用 threadInfo.getWaitingCount() 前,必须确保该 ThreadInfo 包含了锁信息。典型步骤如下:
- 获取
ThreadMXBean实例:ThreadMXBean bean = ManagementFactory.getThreadMXBean(); - 启用锁信息采集:
bean.setThreadContentionMonitoringEnabled(true);(可选,但推荐) - 调用带参数的
getThreadInfo方法,第三个参数设为true(表示包含 monitor 和 synchronizer 信息):ThreadInfo ti = bean.getThreadInfo(threadId, true); - 再调用
ti.getWaitingCount()—— 此时若线程正 wait 在某个对象上,该值才有效;否则返回-1(表示不可用)。
常见误区与注意事项
容易误以为它是“某个变量上所有等待线程的数量”,其实它依赖于线程当前的 wait 栈帧和监控信息采集时机:
- 如果线程没在 wait,或 wait 对象不是当前
ThreadInfo记录的锁对象,getWaitingCount()返回-1; - 该值是快照,非实时动态值,多线程环境下可能瞬间变化;
- 不能用它来替代同步逻辑(比如“等 waitingCount 变 0 再继续”),因为缺乏原子性和可见性保证;
- 调试或监控可用,但生产代码中不应依赖此值做业务判断。
简单示例:观察 wait 队列变化
假设有一个共享对象 lockObj,三个线程先后执行 lockObj.wait():
- 主线程调用
bean.getThreadInfo(tid, true)获取某等待线程的 info; - 此时
ti.getWaitingCount()可能返回2(表示除自身外还有两个线程在同个对象上 wait); - 另一个线程调用
lockObj.notify()后,再次采集,该值通常减 1(取决于 JVM 调度)。
实际值需结合 ti.getLockName() 和 ti.getLockedSynchronizers() 综合判断是否指向目标对象。











