1 7 8 package java.util.concurrent.locks; 9 import java.util.concurrent.*; 10 import java.util.concurrent.atomic.*; 11 import java.util.*; 12 13 153 public class ReentrantReadWriteLock implements ReadWriteLock , java.io.Serializable { 154 private static final long serialVersionUID = -6992448646407690164L; 155 156 private final ReentrantReadWriteLock.ReadLock readerLock; 157 158 private final ReentrantReadWriteLock.WriteLock writerLock; 159 160 private final Sync sync; 161 162 166 public ReentrantReadWriteLock() { 167 sync = new NonfairSync(); 168 readerLock = new ReadLock(this); 169 writerLock = new WriteLock(this); 170 } 171 172 178 public ReentrantReadWriteLock(boolean fair) { 179 sync = (fair)? new FairSync() : new NonfairSync(); 180 readerLock = new ReadLock(this); 181 writerLock = new WriteLock(this); 182 } 183 184 public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } 185 public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; } 186 187 193 194 static final int SHARED_SHIFT = 16; 195 static final int SHARED_UNIT = (1 << SHARED_SHIFT); 196 static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; 197 198 199 static int sharedCount(int c) { return c >>> SHARED_SHIFT; } 200 201 static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; } 202 203 207 abstract static class Sync extends AbstractQueuedSynchronizer { 208 209 transient Thread owner; 210 211 214 abstract void wlock(); 215 216 221 final boolean nonfairTryAcquire(int acquires) { 222 acquires = exclusiveCount(acquires); 224 Thread current = Thread.currentThread(); 225 int c = getState(); 226 int w = exclusiveCount(c); 227 if (w + acquires >= SHARED_UNIT) 228 throw new Error ("Maximum lock count exceeded"); 229 if (c != 0 && (w == 0 || current != owner)) 230 return false; 231 if (!compareAndSetState(c, c + acquires)) 232 return false; 233 owner = current; 234 return true; 235 } 236 237 240 final int nonfairTryAcquireShared(int acquires) { 241 for (;;) { 242 int c = getState(); 243 int nextc = c + (acquires << SHARED_SHIFT); 244 if (nextc < c) 245 throw new Error ("Maximum lock count exceeded"); 246 if (exclusiveCount(c) != 0 && 247 owner != Thread.currentThread()) 248 return -1; 249 if (compareAndSetState(c, nextc)) 250 return 1; 251 } 253 } 254 255 protected final boolean tryRelease(int releases) { 256 Thread current = Thread.currentThread(); 257 int c = getState(); 258 if (owner != current) 259 throw new IllegalMonitorStateException (); 260 int nextc = c - releases; 261 boolean free = false; 262 if (exclusiveCount(c) == releases) { 263 free = true; 264 owner = null; 265 } 266 setState(nextc); 267 return free; 268 } 269 270 protected final boolean tryReleaseShared(int releases) { 271 for (;;) { 272 int c = getState(); 273 int nextc = c - (releases << SHARED_SHIFT); 274 if (nextc < 0) 275 throw new IllegalMonitorStateException (); 276 if (compareAndSetState(c, nextc)) 277 return nextc == 0; 278 } 279 } 280 281 protected final boolean isHeldExclusively() { 282 return exclusiveCount(getState()) != 0 && 283 owner == Thread.currentThread(); 284 } 285 286 288 final ConditionObject newCondition() { 289 return new ConditionObject(); 290 } 291 292 final Thread getOwner() { 293 int c = exclusiveCount(getState()); 294 Thread o = owner; 295 return (c == 0)? null : o; 296 } 297 298 final int getReadLockCount() { 299 return sharedCount(getState()); 300 } 301 302 final boolean isWriteLocked() { 303 return exclusiveCount(getState()) != 0; 304 } 305 306 final int getWriteHoldCount() { 307 int c = exclusiveCount(getState()); 308 Thread o = owner; 309 return (o == Thread.currentThread())? c : 0; 310 } 311 312 316 private void readObject(java.io.ObjectInputStream s) 317 throws java.io.IOException , ClassNotFoundException { 318 s.defaultReadObject(); 319 setState(0); } 321 322 final int getCount() { return getState(); } 323 } 324 325 328 final static class NonfairSync extends Sync { 329 protected final boolean tryAcquire(int acquires) { 330 return nonfairTryAcquire(acquires); 331 } 332 333 protected final int tryAcquireShared(int acquires) { 334 return nonfairTryAcquireShared(acquires); 335 } 336 337 final void wlock() { 339 if (compareAndSetState(0, 1)) 340 owner = Thread.currentThread(); 341 else 342 acquire(1); 343 } 344 } 345 346 349 final static class FairSync extends Sync { 350 protected final boolean tryAcquire(int acquires) { 351 acquires = exclusiveCount(acquires); 353 Thread current = Thread.currentThread(); 354 Thread first; 355 int c = getState(); 356 int w = exclusiveCount(c); 357 if (w + acquires >= SHARED_UNIT) 358 throw new Error ("Maximum lock count exceeded"); 359 if ((w == 0 || current != owner) && 360 (c != 0 || 361 ((first = getFirstQueuedThread()) != null && 362 first != current))) 363 return false; 364 if (!compareAndSetState(c, c + acquires)) 365 return false; 366 owner = current; 367 return true; 368 } 369 370 protected final int tryAcquireShared(int acquires) { 371 Thread current = Thread.currentThread(); 372 for (;;) { 373 int c = getState(); 374 if (exclusiveCount(c) != 0) { 375 if (owner != current) 376 return -1; 377 } else { 378 Thread first = getFirstQueuedThread(); 379 if (first != null && first != current) 380 return -1; 381 } 382 int nextc = c + (acquires << SHARED_SHIFT); 383 if (nextc < c) 384 throw new Error ("Maximum lock count exceeded"); 385 if (compareAndSetState(c, nextc)) 386 return 1; 387 } 389 } 390 391 final void wlock() { acquire(1); 393 } 394 } 395 396 399 public static class ReadLock implements Lock , java.io.Serializable { 400 private static final long serialVersionUID = -5992448646407690164L; 401 private final Sync sync; 402 403 408 protected ReadLock(ReentrantReadWriteLock lock) { 409 sync = lock.sync; 410 } 411 412 422 public void lock() { 423 sync.acquireShared(1); 424 } 425 426 467 public void lockInterruptibly() throws InterruptedException { 468 sync.acquireSharedInterruptibly(1); 469 } 470 471 494 public boolean tryLock() { 495 return sync.nonfairTryAcquireShared(1) >= 0; 496 } 497 498 565 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { 566 return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); 567 } 568 569 575 public void unlock() { 576 sync.releaseShared(1); 577 } 578 579 584 public Condition newCondition() { 585 throw new UnsupportedOperationException (); 586 } 587 588 595 public String toString() { 596 int r = sync.getReadLockCount(); 597 return super.toString() + 598 "[Read locks = " + r + "]"; 599 } 600 601 } 602 603 606 public static class WriteLock implements Lock , java.io.Serializable { 607 private static final long serialVersionUID = -4992448646407690164L; 608 private final Sync sync; 609 610 615 protected WriteLock(ReentrantReadWriteLock lock) { 616 sync = lock.sync; 617 } 618 619 636 public void lock() { 637 sync.wlock(); 638 } 639 640 691 public void lockInterruptibly() throws InterruptedException { 692 sync.acquireInterruptibly(1); 693 } 694 695 724 public boolean tryLock( ) { 725 return sync.nonfairTryAcquire(1); 726 } 727 728 805 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { 806 return sync.tryAcquireNanos(1, unit.toNanos(timeout)); 807 } 808 809 820 public void unlock() { 821 sync.release(1); 822 } 823 824 866 public Condition newCondition() { 867 return sync.newCondition(); 868 } 869 870 877 public String toString() { 878 Thread owner = sync.getOwner(); 879 return super.toString() + ((owner == null) ? 880 "[Unlocked]" : 881 "[Locked by thread " + owner.getName() + "]"); 882 } 883 884 } 885 886 887 889 893 public final boolean isFair() { 894 return sync instanceof FairSync; 895 } 896 897 906 protected Thread getOwner() { 907 return sync.getOwner(); 908 } 909 910 916 public int getReadLockCount() { 917 return sync.getReadLockCount(); 918 } 919 920 927 public boolean isWriteLocked() { 928 return sync.isWriteLocked(); 929 } 930 931 936 public boolean isWriteLockedByCurrentThread() { 937 return sync.isHeldExclusively(); 938 } 939 940 948 public int getWriteHoldCount() { 949 return sync.getWriteHoldCount(); 950 } 951 952 962 protected Collection<Thread > getQueuedWriterThreads() { 963 return sync.getExclusiveQueuedThreads(); 964 } 965 966 976 protected Collection<Thread > getQueuedReaderThreads() { 977 return sync.getSharedQueuedThreads(); 978 } 979 980 990 public final boolean hasQueuedThreads() { 991 return sync.hasQueuedThreads(); 992 } 993 994 1005 public final boolean hasQueuedThread(Thread thread) { 1006 return sync.isQueued(thread); 1007 } 1008 1009 1018 public final int getQueueLength() { 1019 return sync.getQueueLength(); 1020 } 1021 1022 1032 protected Collection<Thread > getQueuedThreads() { 1033 return sync.getQueuedThreads(); 1034 } 1035 1036 1051 public boolean hasWaiters(Condition condition) { 1052 if (condition == null) 1053 throw new NullPointerException (); 1054 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject )) 1055 throw new IllegalArgumentException ("not owner"); 1056 return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject )condition); 1057 } 1058 1059 1074 public int getWaitQueueLength(Condition condition) { 1075 if (condition == null) 1076 throw new NullPointerException (); 1077 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject )) 1078 throw new IllegalArgumentException ("not owner"); 1079 return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject )condition); 1080 } 1081 1082 1099 protected Collection<Thread > getWaitingThreads(Condition condition) { 1100 if (condition == null) 1101 throw new NullPointerException (); 1102 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject )) 1103 throw new IllegalArgumentException ("not owner"); 1104 return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject )condition); 1105 } 1106 1107 1115 public String toString() { 1116 int c = sync.getCount(); 1117 int w = exclusiveCount(c); 1118 int r = sharedCount(c); 1119 1120 return super.toString() + 1121 "[Write locks = " + w + ", Read locks = " + r + "]"; 1122 } 1123 1124} 1125 | Popular Tags |