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

ReentrantReadWriteLock is confused by the Threads with reused IDs

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 8
    • 7u6, 8
    • core-libs
    • b98
    • generic
    • generic
    • Verified

      Originally described at:
      http://cs.oswego.edu/pipermail/concurrency-interest/2013-June/011449.html

      RRWL stores the thread ID to count the read-lock holders. If the thread read-locks and dies, but some other thread reuses its ID (perfectly legal under Thread.getId() contract), then RRWL treats that new thread as the old one.

      EXAMPLE:

      public static void main(String[] args) throws InterruptedException {
          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
          final CyclicBarrier barrier = new CyclicBarrier(2);
          
          Thread t1 = new LegalThread(1) {

            @Override
            public void run() {
              try {
                lock.readLock().lock();
                barrier.await();
                //T2a locks
                //T2b unlocks
                barrier.await();
                lock.readLock().unlock();
              } catch (Exception e) {
                e.printStackTrace();
              }
            }
          };
          Thread t2a = new LegalThread(2) {

            @Override
            public void run() {
              try {
                //T1 locks
                barrier.await();
                lock.readLock().lock();
              } catch (Exception e) {
                e.printStackTrace();
              }
            }
            
          };
          
          t1.start();
          t2a.start();
          t2a.join();
          
          Thread t2b = new LegalThread(2) {

            @Override
            public void run() {
              try {
                lock.readLock().unlock();
                barrier.await();
              } catch (Exception e) {
                e.printStackTrace();
              }
            }
            
          };
          t2b.start();
        }
        
        static class LegalThread extends Thread {

          private final int id;
          
          public LegalThread(int id) {
            this.id = id;
          }
          
          @Override
          public long getId() {
            return id;
          }
        }

      EXPECTED BEHAVIOR:
      IllegalMonitorStateException in t2b.run()

      ACTUAL BEHAVIOR:
      Everything is "fine".

            dl Doug Lea
            shade Aleksey Shipilev
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: