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

ReentrantReadWriteLock readLock behavior doesn't comply the java api doc

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 6u12, 6u16
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.6.0_12"
      Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
      Java HotSpot(TM) Server VM (build 11.2-b01, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux Freeman-pc 2.6.9-42.ELsmp #1 SMP Wed Jul 12 23:27:17 EDT 2006 i686 i686 i386 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      java version "1.6.0_12"
      Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
      Java HotSpot(TM) Server VM (build 11.2-b01, mixed mode)
      we cannot get a read lock if the sequence is
       * thread 1: rwlock.readLock().lock(); //should sucess to get the readLock
       * thread 2: rwlock.writeLock().lock();//should fail to get the writeLock since the readLock already hold by another thread
       * thread 3: rwlock.readLock().lock(); //should success to get the readLock since no other thread hold the writeLock but failed only with JDK6, (OK with JDK 5)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run the code like
      import java.util.concurrent.locks.*;
      import java.util.concurrent.*;

      /**
       * Test ReentrantReadWrite Lock.
       * This code shows how we cannot get a read lock if the sequence is
       * thread 1: rwlock.readLock().lock(); //should sucess to get the readLock
       * thread 2: rwlock.writeLock().lock();//should fail to get the writeLock since the readLock already hold by another thread
       * thread 3: rwlock.readLock().lock(); //should success to get the readLock since no other thread hold the writeLock but failed only with JDK6, (OK with JDK 5)
       */
      public class TestReadWriteLock {

          void log(String s) {
              System.out.printf("%s: %s%n", Thread.currentThread().getName(), s);
          }


          public static void main(String[] args) throws Exception {

              new TestReadWriteLock().runTest();
          }

          public void runTest() throws Exception {
              ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock(false);

              // obtain read lock
              rwlock.readLock().lock(); //should sucess to get the readLock

              // start 1 threads
              for (int i = 0; i < 1; i++) {
                  new Thread(this.new WriteLockThread(rwlock), "TryWrite" + i).start();
                  Thread.sleep(3000);
                  new Thread(this.new ReadLockThread(rwlock), "TryRead" + i).start();
              }
          }

          class WriteLockThread implements Runnable {

              private ReentrantReadWriteLock rwlock;

              public WriteLockThread(ReentrantReadWriteLock rwlock) {
                  this.rwlock = rwlock;
              }
              public void run() {
                  try {
                      log("try get writelock");
                      rwlock.writeLock().lock(); //should fail to get the writeLock since the readLock already hold by another thread
                      log("can get writelock"); // can't print out
                  } finally {
                  }

              }

          }

          class ReadLockThread implements Runnable {

              private ReentrantReadWriteLock rwlock;

              public ReadLockThread(ReentrantReadWriteLock rwlock) {
                  this.rwlock = rwlock;
              }
              public void run() {
                  try {
                      log("try get readlock");
                      rwlock.readLock().lock();//should success to get the readLock since no other thread hold the writeLock but failed only with JDK6, (OK with JDK 5)
                      log("can get readlock");//get this print out with JDK5 as expected, but not with JDK6, which means the error in JDK6
                  } finally {
                      log("unlock readlock");
                      rwlock.readLock().unlock();
                  }

              }

          }
      }


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      TryWrite0: try get writelock
      TryRead0: try get readlock
      TryRead0: can get readlock
      TryRead0: unlock readlock
      ACTUAL -
      TryWrite0: try get writelock
      TryRead0: try get readlock

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.concurrent.locks.*;
      import java.util.concurrent.*;

      /**
       * Test ReentrantReadWrite Lock.
       * This code shows how we cannot get a read lock if the sequence is
       * thread 1: rwlock.readLock().lock(); //should sucess to get the readLock
       * thread 2: rwlock.writeLock().lock();//should fail to get the writeLock since the readLock already hold by another thread
       * thread 3: rwlock.readLock().lock(); //should success to get the readLock since no other thread hold the writeLock but failed only with JDK6, (OK with JDK 5)
       */
      public class TestReadWriteLock {

          void log(String s) {
              System.out.printf("%s: %s%n", Thread.currentThread().getName(), s);
          }


          public static void main(String[] args) throws Exception {

              new TestReadWriteLock().runTest();
          }

          public void runTest() throws Exception {
              ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock(false);

              // obtain read lock
              rwlock.readLock().lock(); //should sucess to get the readLock

              // start 1 threads
              for (int i = 0; i < 1; i++) {
                  new Thread(this.new WriteLockThread(rwlock), "TryWrite" + i).start();
                  Thread.sleep(3000);
                  new Thread(this.new ReadLockThread(rwlock), "TryRead" + i).start();
              }
          }

          class WriteLockThread implements Runnable {

              private ReentrantReadWriteLock rwlock;

              public WriteLockThread(ReentrantReadWriteLock rwlock) {
                  this.rwlock = rwlock;
              }
              public void run() {
                  try {
                      log("try get writelock");
                      rwlock.writeLock().lock(); //should fail to get the writeLock since the readLock already hold by another thread
                      log("can get writelock"); // can't print out
                  } finally {
                  }

              }

          }

          class ReadLockThread implements Runnable {

              private ReentrantReadWriteLock rwlock;

              public ReadLockThread(ReentrantReadWriteLock rwlock) {
                  this.rwlock = rwlock;
              }
              public void run() {
                  try {
                      log("try get readlock");
                      rwlock.readLock().lock();//should success to get the readLock since no other thread hold the writeLock but failed only with JDK6, (OK with JDK 5)
                      log("can get readlock");//get this print out with JDK5 as expected, but not with JDK6, which means the error in JDK6
                  } finally {
                      log("unlock readlock");
                      rwlock.readLock().unlock();
                  }

              }

          }
      }

      ---------- END SOURCE ----------

            Unassigned Unassigned
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: