Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8176204

[DOC] ThreadMXBean Fails to Detect ReentrantReadWriteLock Deadlock

XMLWordPrintable

        FULL PRODUCT VERSION :
        java version "1.8.0_111"
        Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
        Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [Version 6.1.7601]

        A DESCRIPTION OF THE PROBLEM :
        ThreadMXBean.findDeadlockedThreads() fails to detect a deadlock involving ReentrantReadWriteLock. Here are the steps to reproduce the deadlock.

        ReentrantReadWriteLock lock1, lock2;

        - Thread A: lock1.readLock().lock();
        - Thread B: lock2.readLock().lock();
        - Thread C: lock1.writeLock().lock();
        - Thread D: lock2.writeLock().lock();
        - Thread A: lock2.readLock().lock();
        - Thread B: lock1.readLock().lock();

        The first 2 operations succeed. The rest of the operations cause the threads to block.

        ThreadMXBean doesn't account for Thread C and D causing Thread A and B to block. Hence, ThreadMXBean doesn't report a deadlock.


        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Fix compiler errors in the source code by adding imports and "throws" statements. Run the code.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        bean.findDeadlockedThreads() should return a long[] of the threads involved in the deadlock. "Deadlock detected" should be printed to the screen.
        ACTUAL -
        Nothing is printed to the screen.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        public class Deadlock
        {
           public static void main(String arg[])
           {
              ReentrantReadWriteLock lock1, lock2;
              ThreadMXBean bean;

              lock1 = new ReentrantReadWriteLock();
              lock2 = new ReentrantReadWriteLock();

              new Thread(() -> deadlocker(lock1, lock2)).start();
              new Thread(() -> deadlocker(lock2, lock1)).start();
              new Thread(() -> lockUnlock(lock1.writeLock())).start();
              new Thread(() -> lockUnlock(lock2.writeLock())).start();

              bean = ManagementFactory.getThreadMXBean();

              while (bean.findDeadlockedThreads() == null)
                 Thread.sleep(1000);

              System.out.println("Deadlock detected");
           }

           private static void deadlocker(ReentrantReadWriteLock lock1, ReentrantReadWriteLock lock2) // TODO - Remove this
           {
              lock1.readLock().lock();
              lockUnlock(lock2.readLock());
           }

           private static void lockUnlock(Lock lock)
           {
              while (true)
              {
                 lock.lock();
                 lock.unlock();
              }
           }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        None found yet. I just figured out how to reproduce the deadlock and not have it detected by ThreadMXBean. I now need to write my own deadlock detector so I can figure out how to resolve my deadlock issue.

              asapre Amit Sapre
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              11 Start watching this issue

                Created:
                Updated:
                Resolved: