我正在调试一个运行多个线程的Java应用程序。在查看日志一段时间后,似乎其中一个线程不再运行。我的猜测是线程正在等待一个从未释放的锁(最后一次输出是在调用同步方法之前)。
我是否可以为线程配置一个超时;类似于“等待这个锁,但如果它在10秒后不可用,就不要再等待了!”
发布于 2009-07-28 14:50:22
您可以使用java.util.concurrent.Lock而不是固有的Object锁。没有公平排序的RentrantLock具有与内部锁相同的基本行为和语义。有一个接受超时参数的方法tryLock:
Lock lock = ...;
if (lock.tryLock(10L, TimeUnit.SECONDS)) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}发布于 2009-07-28 14:49:01
您可以使用调试工具或探查器,而不是添加额外的代码进行调试。
一种选择是使用像JConsole (JDK附带的)这样的东西,它包含一个名为“检测死锁”的按钮(至少在Java6中是这样的,我认为它在Java5中不起作用)。另一种选择是生成一个线程转储到控制台--在Unix上,你可以输入"kill -3“,而在Windows CTRL+BRK上就可以了。其他分析工具,如VisualVM (也在JDK中)可以提供帮助。最后是JCarder,它是“一个用于在并发多线程Java程序中查找潜在死锁的开源工具”。
发布于 2009-07-28 14:51:46
您可以让线程共享一个显式锁(参见java.util.concurrent.lock.Lock)。然后可以使用Lock.tryLock(),它可以使用一个可选的超时。
您还可以使用java1.6附带的jstack实用程序(对1.5不太确定),它将打印出所有线程的状态以及它们可能正在等待或可能不等待的内容。只需使用进程id调用它。例如::
> jstack PID
"Signal Dispatcher" daemon prio=10 tid=0x00000000408e8400 nid=0x79a8 runnable [0x0000000000000000..0x000000004143f810]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=10 tid=0x00000000408c9400 nid=0x79a7 in Object.wait() [0x0000000041a7b000..0x0000000041a7bb00]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00007f992d1e7050> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
- locked <0x00007f992d1e7050> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0x00000000408c2000 nid=0x79a6 in Object.wait() [0x000000004197a000..0x000000004197ac80]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00007f992d41a958> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x00007f992d41a958> (a java.lang.ref.Reference$Lock)https://stackoverflow.com/questions/1194606
复制相似问题