如何检测死锁?同步块中的超时?

2022-09-03 16:50:24

我正在调试一个运行多个线程的 Java 应用程序。在查看日志一段时间后,似乎其中一个线程不再运行。我的猜测是线程正在等待一个从未释放的锁(最后一个输出是在调用同步方法之前)。

我可以配置线程的超时吗?一种“等待此锁,但如果它在10秒后不可用,请不要再等待了!


答案 1

您可以使用 java.util.concurrent.Lock 而不是内部锁。没有公平排序的 RentrantLock 具有与内在锁相同的基本行为和语义。有一个方法 tryLock 采用超时参数:Object

Lock lock = ...;
if (lock.tryLock(10L, TimeUnit.SECONDS)) {
    try {
        // manipulate protected state
    } finally {
        lock.unlock();
    }
} else {
      // perform alternative actions
}

答案 2

无需添加额外的代码进行调试,而是可以使用调试工具或探查器。

一种选择是使用像JConsole(随JDK一起提供)的东西,它包含一个名为“Detect Deadlock”的按钮(至少在Java 6中是这样,我认为它在Java 5中不起作用)。另一种选择是生成一个线程转储到控制台 - 在Unix上,您可以键入“kill -3”,而在Windows上CTRL + BRK将起作用。其他分析工具,如VisualVM(也在JDK中)可以提供帮助。最后是JCarder,它是“一个开源工具,用于查找并发多线程Java程序中的潜在死锁”。