我有很多代码&处理器很小,
在调用notifyAll
时,有时会产生性能问题(100ms),所以我想知道当前等待对象被释放的线程是什么。
synchronized (obj){
//do some stuff..
obj.notifyall();
}
我想在调用obj.notifyAll()
答案 0 :(得分:7)
是否所有线程都在资源上等待相同的条件?如果是,那么您可以尝试替换obj.notify()
而不是obj.notifyAll
,但实际上不建议这样做。 AFAIK,没有办法“检索”等待给定对象的所有线程的列表(虽然你可以以编程方式获取进程的线程转储并查看线程,但我确信这不是你所拥有的心神)。即使有,列出线程,然后与他们做“某事”肯定会花费超过notifyAll
所花费的时间。
此外,如果“处理器很小”,请尝试限制产生的线程数量,因为没有相当数量的“真实”线程,创建太多线程通常是开销。这样,notifyAll
就不会唤醒一堆线程。
这是一个小程序,它演示了内联注释的线程状态信息的转储:
package net.sanjayts.test;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.util.concurrent.TimeUnit;
public class ThreadDumpTest {
public static void main(String[] args) throws Exception {
final Object lock = new Object();
for (int i = 0; i < 6; ++i) {
final int cnt = i;
new DaemonThread(new Runnable() {
@Override
public void run() {
try {
// If counter is even, try to acquire common lock and then
// sleep. If odd, sleep without trying to acquire the lock.
// This way, if we do a thread dump, we'll see threads in
// different states (TIMED_WAIT for those sleeping threads
// and BLOCKED for those waiting for the common "lock".
if (cnt % 2 == 0) {
synchronized (lock) {
TimeUnit.MINUTES.sleep(1); // sleep 1 min
}
} else {
TimeUnit.MINUTES.sleep(1); // sleep 1 min
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "mythread-" + cnt).start();
}
ThreadInfo[] infos = ManagementFactory.
getThreadMXBean().dumpAllThreads(true, true);
for (ThreadInfo info : infos) {
System.out.println(info);
System.out.println("===========================");
}
TimeUnit.SECONDS.sleep(2);
}
}
class DaemonThread extends Thread {
public DaemonThread(Runnable r, String name) {
super(r, name);
setDaemon(true);
}
}
答案 1 :(得分:2)
您可以使用Thread.getAllStackTraces()并打印出所有正在等待的线程。