Print this page


Split Close
Expand all
Collapse all
          --- old/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java
          +++ new/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java
↓ open down ↓ 147 lines elided ↑ open up ↑
 148  148   *        rwl.writeLock().lock();
 149  149   *        try {
 150  150   *          // Recheck state because another thread might have
 151  151   *          // acquired write lock and changed state before we did.
 152  152   *          if (!cacheValid) {
 153  153   *            data = ...
 154  154   *            cacheValid = true;
 155  155   *          }
 156  156   *          // Downgrade by acquiring read lock before releasing write lock
 157  157   *          rwl.readLock().lock();
 158      - *        } finally  {
      158 + *        } finally {
 159  159   *          rwl.writeLock().unlock(); // Unlock write, still hold read
 160  160   *        }
 161  161   *     }
 162  162   *
 163  163   *     try {
 164  164   *       use(data);
 165  165   *     } finally {
 166  166   *       rwl.readLock().unlock();
 167  167   *     }
 168  168   *   }
↓ open down ↓ 39 lines elided ↑ open up ↑
 208  208   * <h3>Implementation Notes</h3>
 209  209   *
 210  210   * <p>This lock supports a maximum of 65535 recursive write locks
 211  211   * and 65535 read locks. Attempts to exceed these limits result in
 212  212   * {@link Error} throws from locking methods.
 213  213   *
 214  214   * @since 1.5
 215  215   * @author Doug Lea
 216  216   *
 217  217   */
 218      -public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable  {
      218 +public class ReentrantReadWriteLock
      219 +        implements ReadWriteLock, java.io.Serializable {
 219  220      private static final long serialVersionUID = -6992448646407690164L;
 220  221      /** Inner class providing readlock */
 221  222      private final ReentrantReadWriteLock.ReadLock readerLock;
 222  223      /** Inner class providing writelock */
 223  224      private final ReentrantReadWriteLock.WriteLock writerLock;
 224  225      /** Performs all synchronization mechanics */
 225  226      final Sync sync;
 226  227  
 227  228      /**
 228  229       * Creates a new {@code ReentrantReadWriteLock} with
↓ open down ↓ 15 lines elided ↑ open up ↑
 244  245          writerLock = new WriteLock(this);
 245  246      }
 246  247  
 247  248      public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
 248  249      public ReentrantReadWriteLock.ReadLock  readLock()  { return readerLock; }
 249  250  
 250  251      /**
 251  252       * Synchronization implementation for ReentrantReadWriteLock.
 252  253       * Subclassed into fair and nonfair versions.
 253  254       */
 254      -    static abstract class Sync extends AbstractQueuedSynchronizer {
      255 +    abstract static class Sync extends AbstractQueuedSynchronizer {
 255  256          private static final long serialVersionUID = 6317671515068378041L;
 256  257  
 257  258          /*
 258  259           * Read vs write count extraction constants and functions.
 259  260           * Lock state is logically divided into two unsigned shorts:
 260  261           * The lower one representing the exclusive (writer) lock hold count,
 261  262           * and the upper the shared (reader) hold count.
 262  263           */
 263  264  
 264  265          static final int SHARED_SHIFT   = 16;
↓ open down ↓ 346 lines elided ↑ open up ↑
 611  612          }
 612  613  
 613  614          // Methods relayed to outer class
 614  615  
 615  616          final ConditionObject newCondition() {
 616  617              return new ConditionObject();
 617  618          }
 618  619  
 619  620          final Thread getOwner() {
 620  621              // Must read state before owner to ensure memory consistency
 621      -            return ((exclusiveCount(getState()) == 0)?
      622 +            return ((exclusiveCount(getState()) == 0) ?
 622  623                      null :
 623  624                      getExclusiveOwnerThread());
 624  625          }
 625  626  
 626  627          final int getReadLockCount() {
 627  628              return sharedCount(getState());
 628  629          }
 629  630  
 630  631          final boolean isWriteLocked() {
 631  632              return exclusiveCount(getState()) != 0;
↓ open down ↓ 30 lines elided ↑ open up ↑
 662  663              readHolds = new ThreadLocalHoldCounter();
 663  664              setState(0); // reset to unlocked state
 664  665          }
 665  666  
 666  667          final int getCount() { return getState(); }
 667  668      }
 668  669  
 669  670      /**
 670  671       * Nonfair version of Sync
 671  672       */
 672      -    final static class NonfairSync extends Sync {
      673 +    static final class NonfairSync extends Sync {
 673  674          private static final long serialVersionUID = -8159625535654395037L;
 674  675          final boolean writerShouldBlock() {
 675  676              return false; // writers can always barge
 676  677          }
 677  678          final boolean readerShouldBlock() {
 678  679              /* As a heuristic to avoid indefinite writer starvation,
 679  680               * block if the thread that momentarily appears to be head
 680  681               * of queue, if one exists, is a waiting writer.  This is
 681  682               * only a probabilistic effect since a new reader will not
 682  683               * block if there is a waiting writer behind other enabled
 683  684               * readers that have not yet drained from the queue.
 684  685               */
 685  686              return apparentlyFirstQueuedIsExclusive();
 686  687          }
 687  688      }
 688  689  
 689  690      /**
 690  691       * Fair version of Sync
 691  692       */
 692      -    final static class FairSync extends Sync {
      693 +    static final class FairSync extends Sync {
 693  694          private static final long serialVersionUID = -2274990926593161451L;
 694  695          final boolean writerShouldBlock() {
 695  696              return hasQueuedPredecessors();
 696  697          }
 697  698          final boolean readerShouldBlock() {
 698  699              return hasQueuedPredecessors();
 699  700          }
 700  701      }
 701  702  
 702  703      /**
 703  704       * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
 704  705       */
 705      -    public static class ReadLock implements Lock, java.io.Serializable  {
      706 +    public static class ReadLock implements Lock, java.io.Serializable {
 706  707          private static final long serialVersionUID = -5992448646407690164L;
 707  708          private final Sync sync;
 708  709  
 709  710          /**
 710  711           * Constructor for use by subclasses
 711  712           *
 712  713           * @param lock the outer lock object
 713  714           * @throws NullPointerException if the lock is null
 714  715           */
 715  716          protected ReadLock(ReentrantReadWriteLock lock) {
↓ open down ↓ 144 lines elided ↑ open up ↑
 860  861           * the interrupt over normal or reentrant acquisition of the
 861  862           * lock, and over reporting the elapse of the waiting time.
 862  863           *
 863  864           * @param timeout the time to wait for the read lock
 864  865           * @param unit the time unit of the timeout argument
 865  866           * @return {@code true} if the read lock was acquired
 866  867           * @throws InterruptedException if the current thread is interrupted
 867  868           * @throws NullPointerException if the time unit is null
 868  869           *
 869  870           */
 870      -        public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
      871 +        public boolean tryLock(long timeout, TimeUnit unit)
      872 +                throws InterruptedException {
 871  873              return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
 872  874          }
 873  875  
 874  876          /**
 875  877           * Attempts to release this lock.
 876  878           *
 877  879           * <p> If the number of readers is now zero then the lock
 878  880           * is made available for write lock attempts.
 879  881           */
 880  882          public  void unlock() {
↓ open down ↓ 20 lines elided ↑ open up ↑
 901  903          public String toString() {
 902  904              int r = sync.getReadLockCount();
 903  905              return super.toString() +
 904  906                  "[Read locks = " + r + "]";
 905  907          }
 906  908      }
 907  909  
 908  910      /**
 909  911       * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
 910  912       */
 911      -    public static class WriteLock implements Lock, java.io.Serializable  {
      913 +    public static class WriteLock implements Lock, java.io.Serializable {
 912  914          private static final long serialVersionUID = -4992448646407690164L;
 913  915          private final Sync sync;
 914  916  
 915  917          /**
 916  918           * Constructor for use by subclasses
 917  919           *
 918  920           * @param lock the outer lock object
 919  921           * @throws NullPointerException if the lock is null
 920  922           */
 921  923          protected WriteLock(ReentrantReadWriteLock lock) {
↓ open down ↓ 179 lines elided ↑ open up ↑
1101 1103           *
1102 1104           * @return {@code true} if the lock was free and was acquired
1103 1105           * by the current thread, or the write lock was already held by the
1104 1106           * current thread; and {@code false} if the waiting time
1105 1107           * elapsed before the lock could be acquired.
1106 1108           *
1107 1109           * @throws InterruptedException if the current thread is interrupted
1108 1110           * @throws NullPointerException if the time unit is null
1109 1111           *
1110 1112           */
1111      -        public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
     1113 +        public boolean tryLock(long timeout, TimeUnit unit)
     1114 +                throws InterruptedException {
1112 1115              return sync.tryAcquireNanos(1, unit.toNanos(timeout));
1113 1116          }
1114 1117  
1115 1118          /**
1116 1119           * Attempts to release this lock.
1117 1120           *
1118 1121           * <p>If the current thread is the holder of this lock then
1119 1122           * the hold count is decremented. If the hold count is now
1120 1123           * zero then the lock is released.  If the current thread is
1121 1124           * not the holder of this lock then {@link
↓ open down ↓ 362 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX