Programmatic deadlock detection in java

前端 未结 9 1351
无人及你
无人及你 2020-11-29 17:36

How can I programmatically detect that a deadlock has occurred in a Java program?

相关标签:
9条回答
  • 2020-11-29 17:55

    In case you want it to be done in run-time you can use watchdog for that.

    0 讨论(0)
  • 2020-11-29 18:01

    There is code here: http://www.java2s.com/Code/Java/Development-Class/PerformingdeadlockdetectionprogrammaticallywithintheapplicationusingthejavalangmanagementAPI.htm

    The magic happens in ThreadMonitor.findDeadlock():

      public boolean findDeadlock() {
        long[] tids;
        if (findDeadlocksMethodName.equals("findDeadlockedThreads")
            && tmbean.isSynchronizerUsageSupported()) {
          tids = tmbean.findDeadlockedThreads();
          if (tids == null) {
            return false;
          }
    
          System.out.println("Deadlock found :-");
          ThreadInfo[] infos = tmbean.getThreadInfo(tids, true, true);
          for (ThreadInfo ti : infos) {
            printThreadInfo(ti);
            printLockInfo(ti.getLockedSynchronizers());
            System.out.println();
          }
        } else {
          tids = tmbean.findMonitorDeadlockedThreads();
          if (tids == null) {
            return false;
          }
          ThreadInfo[] infos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE);
          for (ThreadInfo ti : infos) {
            // print thread information
            printThreadInfo(ti);
          }
        }
    
        return true;
      }
    

    This calls an API of the ThreadMXBean which has a different name in Java 5 and 6 (hence the outer if()).

    The code example also allows to interrupt the locks, so you can even break the deadlock.

    0 讨论(0)
  • 2020-11-29 18:06

    JArmus is a library for deadlock detection and avoidance. It includes support for: Thread.join, CyclicBarrier, CountDownLatch, Phaser, and ReentrantLock.

    To use JArmus you need to instrument your code. Either through one of its instrumented classes or automatically with the JArmus instrumentar jarmusc.

    java -jar jarmusc.jar yourprogram.jar checkedprogram.jar

    The input yourprogram.jar is the program you want to check. The output is the same program with checks to automatically find any deadlock.

    Barriers need some help

    Verifying deadlocks with classes CyclicBarrier, CountDownLatch, Phaser is a bit tricky --- for example, JConsole cannot detect these types of deadlocks. JArmus needs a little help from you: you must specify which threads are influencing synchronization, we call these registered threads.

    As soon as possible, the thread must mark itself as registered. A good place to mark registered threads is at the beginning method Runnable.run. JArmus.register(latch);

    Example

    The following program that deadlocks is correctly identified by JArmus:

    final CountDownLatch latch = new CountDownLatch(2);
    final CyclicBarrier barrier = new CyclicBarrier(2);
    final Queue<Exception> exceptions = new ArrayDeque<>();
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                JArmus.register(barrier); // do not forget to register!
                JArmus.register(latch); // do not forget to register!
                latch.countDown();
                latch.await();
                barrier.await();
            } catch (Exception e) {
                exceptions.add(e);
            }
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                JArmus.register(barrier); // do not forget to register!
                JArmus.register(latch); // do not forget to register!
                barrier.await();
                latch.countDown();
                latch.await();
            } catch (Exception e) {
                exceptions.add(e);
            }
        }
    });
    t1.start();
    t2.start();
    
    0 讨论(0)
  • 2020-11-29 18:06

    tempus-fugit also implements it along with a programmatic thread dumping class. It's implemented using the mbean mechanism mentioned above and offers a drop in, out-of-the-box super duper solution.

    0 讨论(0)
  • 2020-11-29 18:07

    You might want to consider IBM's MTRAT. Prevention is better than cure after all. The Multicore Software Development Kit also comes with a deadlock detection tool.

    0 讨论(0)
  • 2020-11-29 18:09

    You can detect the deadlocked threads programmatically using ThreadMXBean class.Here is the code,

        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
    
        long ids[] = bean.findMonitorDeadlockedThreads();
    
        if(ids != null)
        {
            ThreadInfo threadInfo[] = bean.getThreadInfo(ids);
    
            for (ThreadInfo threadInfo1 : threadInfo)
            {
                System.out.println(threadInfo1.getThreadId());    //Prints the ID of deadlocked thread
    
                System.out.println(threadInfo1.getThreadName());  //Prints the name of deadlocked thread
    
                System.out.println(threadInfo1.getLockName());    //Prints the string representation of an object for which thread has entered into deadlock.
    
                System.out.println(threadInfo1.getLockOwnerId());  //Prints the ID of thread which currently owns the object lock
    
                System.out.println(threadInfo1.getLockOwnerName());  //Prints name of the thread which currently owns the object lock.
            }
        }
        else
        {
            System.out.println("No Deadlocked Threads");
        }
    

    Click here for more info on how to detect the deadlocked threads.

    0 讨论(0)
提交回复
热议问题