有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

我可以为线程配置一个超时;一种“等待此锁,但如果10秒后它不可用,请不要再等待!”


共 (5) 个答案

  1. # 1 楼答案

    不能对传统的同步方法使用超时。但是,使用“新”java。util。同时,您可以使用支持超时的程序锁

    例如,看看java.util.concurrent.locks.ReentrantLock

    A reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities.

  2. # 2 楼答案

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

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

    您可以让线程共享一个显式锁(请参阅java.util.concurrent.lock.lock)。然后可以使用锁。tryLock(),它可能需要一个可选的超时

    您还可以使用Java1.6(不确定1.5)附带的jstack实用程序,它将打印出所有线程的状态以及它们可能等待或不等待的内容。只需使用进程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)
    
  4. # 4 楼答案

    您可以使用调试工具或分析器,而不是添加额外的调试代码

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

  5. # 5 楼答案

    虽然在等待同步方法上的锁时可能会出现超时,但实现这些方法很难。基本上你会产生一个定时器线程,它会在T秒后中断块线程。。。不太好

    如果您使用的是Java5或更高版本,我强烈建议您看看新的并发类提供了什么。例如,您可以考虑使用ReentrantLock,它有一个方法tryLock(long timeout, TimeUnit unit),它允许您尝试获取锁,但允许您在固定的时间之后逃逸。p>