| /* |
| * Written by Doug Lea with assistance from members of JCP JSR-166 |
| * Expert Group and released to the public domain, as explained at |
| * http://creativecommons.org/licenses/publicdomain |
| * Other contributors include Andrew Wright, Jeffrey Hayes, |
| * Pat Fisher, Mike Judd. |
| */ |
| |
| package tests.api.java.util.concurrent; // android-added |
| |
| import junit.framework.*; |
| import java.util.concurrent.locks.*; |
| import java.util.concurrent.*; |
| import static java.util.concurrent.TimeUnit.MILLISECONDS; |
| import java.io.*; |
| import java.util.*; |
| |
| public class ReentrantReadWriteLockTest extends JSR166TestCase { |
| public static Test suite() { |
| return new TestSuite(ReentrantReadWriteLockTest.class); |
| } |
| |
| /** |
| * A runnable calling lockInterruptibly |
| */ |
| class InterruptibleLockRunnable extends CheckedRunnable { |
| final ReentrantReadWriteLock lock; |
| InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; } |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lockInterruptibly(); |
| } |
| } |
| |
| |
| /** |
| * A runnable calling lockInterruptibly that expects to be |
| * interrupted |
| */ |
| class InterruptedLockRunnable extends CheckedInterruptedRunnable { |
| final ReentrantReadWriteLock lock; |
| InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; } |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lockInterruptibly(); |
| } |
| } |
| |
| /** |
| * Subclass to expose protected methods |
| */ |
| static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock { |
| PublicReentrantReadWriteLock() { super(); } |
| public Collection<Thread> getQueuedThreads() { |
| return super.getQueuedThreads(); |
| } |
| public Collection<Thread> getWaitingThreads(Condition c) { |
| return super.getWaitingThreads(c); |
| } |
| } |
| |
| /** |
| * Constructor sets given fairness, and is in unlocked state |
| */ |
| public void testConstructor() { |
| ReentrantReadWriteLock rl = new ReentrantReadWriteLock(); |
| assertFalse(rl.isFair()); |
| assertFalse(rl.isWriteLocked()); |
| assertEquals(0, rl.getReadLockCount()); |
| ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true); |
| assertTrue(r2.isFair()); |
| assertFalse(r2.isWriteLocked()); |
| assertEquals(0, r2.getReadLockCount()); |
| ReentrantReadWriteLock r3 = new ReentrantReadWriteLock(false); |
| assertFalse(r3.isFair()); |
| assertFalse(r3.isWriteLocked()); |
| assertEquals(0, r3.getReadLockCount()); |
| } |
| |
| /** |
| * write-locking and read-locking an unlocked lock succeed |
| */ |
| public void testLock() { |
| ReentrantReadWriteLock rl = new ReentrantReadWriteLock(); |
| rl.writeLock().lock(); |
| assertTrue(rl.isWriteLocked()); |
| assertTrue(rl.isWriteLockedByCurrentThread()); |
| assertTrue(rl.writeLock().isHeldByCurrentThread()); |
| assertEquals(0, rl.getReadLockCount()); |
| rl.writeLock().unlock(); |
| assertFalse(rl.isWriteLocked()); |
| assertFalse(rl.isWriteLockedByCurrentThread()); |
| assertFalse(rl.writeLock().isHeldByCurrentThread()); |
| assertEquals(0, rl.getReadLockCount()); |
| rl.readLock().lock(); |
| assertFalse(rl.isWriteLocked()); |
| assertFalse(rl.isWriteLockedByCurrentThread()); |
| assertEquals(1, rl.getReadLockCount()); |
| rl.readLock().unlock(); |
| assertFalse(rl.isWriteLocked()); |
| assertFalse(rl.isWriteLockedByCurrentThread()); |
| assertEquals(0, rl.getReadLockCount()); |
| } |
| |
| |
| /** |
| * locking an unlocked fair lock succeeds |
| */ |
| public void testFairLock() { |
| ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true); |
| rl.writeLock().lock(); |
| assertTrue(rl.isWriteLocked()); |
| assertTrue(rl.isWriteLockedByCurrentThread()); |
| assertTrue(rl.writeLock().isHeldByCurrentThread()); |
| assertEquals(0, rl.getReadLockCount()); |
| rl.writeLock().unlock(); |
| assertFalse(rl.isWriteLocked()); |
| assertFalse(rl.isWriteLockedByCurrentThread()); |
| assertFalse(rl.writeLock().isHeldByCurrentThread()); |
| assertEquals(0, rl.getReadLockCount()); |
| rl.readLock().lock(); |
| assertFalse(rl.isWriteLocked()); |
| assertFalse(rl.isWriteLockedByCurrentThread()); |
| assertEquals(1, rl.getReadLockCount()); |
| rl.readLock().unlock(); |
| assertFalse(rl.isWriteLocked()); |
| assertFalse(rl.isWriteLockedByCurrentThread()); |
| assertEquals(0, rl.getReadLockCount()); |
| } |
| |
| /** |
| * getWriteHoldCount returns number of recursive holds |
| */ |
| public void testGetWriteHoldCount() { |
| ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| for (int i = 1; i <= SIZE; i++) { |
| lock.writeLock().lock(); |
| assertEquals(i,lock.getWriteHoldCount()); |
| } |
| for (int i = SIZE; i > 0; i--) { |
| lock.writeLock().unlock(); |
| assertEquals(i-1,lock.getWriteHoldCount()); |
| } |
| } |
| |
| /** |
| * WriteLock.getHoldCount returns number of recursive holds |
| */ |
| public void testGetHoldCount() { |
| ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| for (int i = 1; i <= SIZE; i++) { |
| lock.writeLock().lock(); |
| assertEquals(i,lock.writeLock().getHoldCount()); |
| } |
| for (int i = SIZE; i > 0; i--) { |
| lock.writeLock().unlock(); |
| assertEquals(i-1,lock.writeLock().getHoldCount()); |
| } |
| } |
| |
| /** |
| * getReadHoldCount returns number of recursive holds |
| */ |
| public void testGetReadHoldCount() { |
| ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| for (int i = 1; i <= SIZE; i++) { |
| lock.readLock().lock(); |
| assertEquals(i,lock.getReadHoldCount()); |
| } |
| for (int i = SIZE; i > 0; i--) { |
| lock.readLock().unlock(); |
| assertEquals(i-1,lock.getReadHoldCount()); |
| } |
| } |
| |
| |
| /** |
| * write-unlocking an unlocked lock throws IllegalMonitorStateException |
| */ |
| public void testUnlock_IllegalMonitorStateException() { |
| ReentrantReadWriteLock rl = new ReentrantReadWriteLock(); |
| try { |
| rl.writeLock().unlock(); |
| shouldThrow(); |
| } catch (IllegalMonitorStateException success) {} |
| } |
| |
| |
| /** |
| * write-lockInterruptibly is interruptible |
| */ |
| public void testWriteLockInterruptibly_Interrupted() throws Exception { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| Thread t = new Thread(new CheckedInterruptedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lockInterruptibly(); |
| lock.writeLock().unlock(); |
| lock.writeLock().lockInterruptibly(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| lock.writeLock().lock(); |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.interrupt(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().unlock(); |
| t.join(); |
| } |
| |
| /** |
| * timed write-tryLock is interruptible |
| */ |
| public void testWriteTryLock_Interrupted() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t = new Thread(new CheckedInterruptedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().tryLock(SMALL_DELAY_MS, MILLISECONDS); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.interrupt(); |
| lock.writeLock().unlock(); |
| t.join(); |
| } |
| |
| /** |
| * read-lockInterruptibly is interruptible |
| */ |
| public void testReadLockInterruptibly_Interrupted() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t = new Thread(new CheckedInterruptedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.readLock().lockInterruptibly(); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.interrupt(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().unlock(); |
| t.join(); |
| } |
| |
| /** |
| * timed read-tryLock is interruptible |
| */ |
| public void testReadTryLock_Interrupted() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t = new Thread(new CheckedInterruptedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.readLock().tryLock(LONG_DELAY_MS, MILLISECONDS); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.interrupt(); |
| t.join(); |
| } |
| |
| |
| /** |
| * write-tryLock fails if locked |
| */ |
| public void testWriteTryLockWhenLocked() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| threadAssertFalse(lock.writeLock().tryLock()); |
| }}); |
| |
| t.start(); |
| t.join(); |
| lock.writeLock().unlock(); |
| } |
| |
| /** |
| * read-tryLock fails if locked |
| */ |
| public void testReadTryLockWhenLocked() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| threadAssertFalse(lock.readLock().tryLock()); |
| }}); |
| |
| t.start(); |
| t.join(); |
| lock.writeLock().unlock(); |
| } |
| |
| /** |
| * Multiple threads can hold a read lock when not write-locked |
| */ |
| public void testMultipleReadLocks() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.readLock().lock(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| threadAssertTrue(lock.readLock().tryLock()); |
| lock.readLock().unlock(); |
| }}); |
| |
| t.start(); |
| t.join(); |
| lock.readLock().unlock(); |
| } |
| |
| /** |
| * A writelock succeeds after reading threads unlock |
| */ |
| public void testWriteAfterMultipleReadLocks() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.readLock().lock(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| }}); |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t1.start(); |
| t2.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.readLock().unlock(); |
| t1.join(MEDIUM_DELAY_MS); |
| t2.join(MEDIUM_DELAY_MS); |
| assertTrue(!t1.isAlive()); |
| assertTrue(!t2.isAlive()); |
| } |
| |
| /** |
| * Readlocks succeed after a writing thread unlocks |
| */ |
| public void testReadAfterWriteLock() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| }}); |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| }}); |
| |
| t1.start(); |
| t2.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().unlock(); |
| t1.join(MEDIUM_DELAY_MS); |
| t2.join(MEDIUM_DELAY_MS); |
| assertTrue(!t1.isAlive()); |
| assertTrue(!t2.isAlive()); |
| } |
| |
| /** |
| * Read trylock succeeds if write locked by current thread |
| */ |
| public void testReadHoldingWriteLock() { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| assertTrue(lock.readLock().tryLock()); |
| lock.readLock().unlock(); |
| lock.writeLock().unlock(); |
| } |
| |
| /** |
| * Read lock succeeds if write locked by current thread even if |
| * other threads are waiting for readlock |
| */ |
| public void testReadHoldingWriteLock2() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| }}); |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| }}); |
| |
| t1.start(); |
| t2.start(); |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| lock.writeLock().unlock(); |
| t1.join(MEDIUM_DELAY_MS); |
| t2.join(MEDIUM_DELAY_MS); |
| assertTrue(!t1.isAlive()); |
| assertTrue(!t2.isAlive()); |
| } |
| |
| /** |
| * Read lock succeeds if write locked by current thread even if |
| * other threads are waiting for writelock |
| */ |
| public void testReadHoldingWriteLock3() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| }}); |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t1.start(); |
| t2.start(); |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| lock.writeLock().unlock(); |
| t1.join(MEDIUM_DELAY_MS); |
| t2.join(MEDIUM_DELAY_MS); |
| assertTrue(!t1.isAlive()); |
| assertTrue(!t2.isAlive()); |
| } |
| |
| |
| /** |
| * Write lock succeeds if write locked by current thread even if |
| * other threads are waiting for writelock |
| */ |
| public void testWriteHoldingWriteLock4() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| }}); |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t1.start(); |
| t2.start(); |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| lock.writeLock().unlock(); |
| t1.join(MEDIUM_DELAY_MS); |
| t2.join(MEDIUM_DELAY_MS); |
| assertTrue(!t1.isAlive()); |
| assertTrue(!t2.isAlive()); |
| } |
| |
| |
| /** |
| * Fair Read trylock succeeds if write locked by current thread |
| */ |
| public void testReadHoldingWriteLockFair() { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); |
| lock.writeLock().lock(); |
| assertTrue(lock.readLock().tryLock()); |
| lock.readLock().unlock(); |
| lock.writeLock().unlock(); |
| } |
| |
| /** |
| * Fair Read lock succeeds if write locked by current thread even if |
| * other threads are waiting for readlock |
| */ |
| public void testReadHoldingWriteLockFair2() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); |
| lock.writeLock().lock(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| }}); |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| }}); |
| |
| t1.start(); |
| t2.start(); |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| lock.writeLock().unlock(); |
| t1.join(MEDIUM_DELAY_MS); |
| t2.join(MEDIUM_DELAY_MS); |
| assertTrue(!t1.isAlive()); |
| assertTrue(!t2.isAlive()); |
| } |
| |
| |
| /** |
| * Fair Read lock succeeds if write locked by current thread even if |
| * other threads are waiting for writelock |
| */ |
| public void testReadHoldingWriteLockFair3() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); |
| lock.writeLock().lock(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| }}); |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t1.start(); |
| t2.start(); |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.readLock().lock(); |
| lock.readLock().unlock(); |
| lock.writeLock().unlock(); |
| t1.join(MEDIUM_DELAY_MS); |
| t2.join(MEDIUM_DELAY_MS); |
| assertTrue(!t1.isAlive()); |
| assertTrue(!t2.isAlive()); |
| } |
| |
| |
| /** |
| * Fair Write lock succeeds if write locked by current thread even if |
| * other threads are waiting for writelock |
| */ |
| public void testWriteHoldingWriteLockFair4() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); |
| lock.writeLock().lock(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| }}); |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t1.start(); |
| t2.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertTrue(lock.isWriteLockedByCurrentThread()); |
| assertTrue(lock.getWriteHoldCount() == 1); |
| lock.writeLock().lock(); |
| assertTrue(lock.getWriteHoldCount() == 2); |
| lock.writeLock().unlock(); |
| lock.writeLock().lock(); |
| lock.writeLock().unlock(); |
| lock.writeLock().unlock(); |
| t1.join(MEDIUM_DELAY_MS); |
| t2.join(MEDIUM_DELAY_MS); |
| assertTrue(!t1.isAlive()); |
| assertTrue(!t2.isAlive()); |
| } |
| |
| |
| /** |
| * Read tryLock succeeds if readlocked but not writelocked |
| */ |
| public void testTryLockWhenReadLocked() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.readLock().lock(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| threadAssertTrue(lock.readLock().tryLock()); |
| lock.readLock().unlock(); |
| }}); |
| |
| t.start(); |
| t.join(); |
| lock.readLock().unlock(); |
| } |
| |
| |
| |
| /** |
| * write tryLock fails when readlocked |
| */ |
| public void testWriteTryLockWhenReadLocked() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.readLock().lock(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| threadAssertFalse(lock.writeLock().tryLock()); |
| }}); |
| |
| t.start(); |
| t.join(); |
| lock.readLock().unlock(); |
| } |
| |
| |
| /** |
| * Fair Read tryLock succeeds if readlocked but not writelocked |
| */ |
| public void testTryLockWhenReadLockedFair() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); |
| lock.readLock().lock(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| threadAssertTrue(lock.readLock().tryLock()); |
| lock.readLock().unlock(); |
| }}); |
| |
| t.start(); |
| t.join(); |
| lock.readLock().unlock(); |
| } |
| |
| |
| |
| /** |
| * Fair write tryLock fails when readlocked |
| */ |
| public void testWriteTryLockWhenReadLockedFair() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); |
| lock.readLock().lock(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() { |
| threadAssertFalse(lock.writeLock().tryLock()); |
| }}); |
| |
| t.start(); |
| t.join(); |
| lock.readLock().unlock(); |
| } |
| |
| |
| |
| /** |
| * write timed tryLock times out if locked |
| */ |
| public void testWriteTryLock_Timeout() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() throws InterruptedException { |
| threadAssertFalse(lock.writeLock().tryLock(1, MILLISECONDS)); |
| }}); |
| |
| t.start(); |
| t.join(); |
| assertTrue(lock.writeLock().isHeldByCurrentThread()); |
| lock.writeLock().unlock(); |
| } |
| |
| /** |
| * read timed tryLock times out if write-locked |
| */ |
| public void testReadTryLock_Timeout() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lock(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() throws InterruptedException { |
| threadAssertFalse(lock.readLock().tryLock(1, MILLISECONDS)); |
| }}); |
| |
| t.start(); |
| t.join(); |
| assertTrue(lock.writeLock().isHeldByCurrentThread()); |
| lock.writeLock().unlock(); |
| } |
| |
| |
| /** |
| * write lockInterruptibly succeeds if lock free else is interruptible |
| */ |
| public void testWriteLockInterruptibly() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lockInterruptibly(); |
| Thread t = new Thread(new CheckedInterruptedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lockInterruptibly(); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.interrupt(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.join(); |
| lock.writeLock().unlock(); |
| } |
| |
| /** |
| * read lockInterruptibly succeeds if lock free else is interruptible |
| */ |
| public void testReadLockInterruptibly() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| lock.writeLock().lockInterruptibly(); |
| Thread t = new Thread(new CheckedInterruptedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.readLock().lockInterruptibly(); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.interrupt(); |
| t.join(); |
| lock.writeLock().unlock(); |
| } |
| |
| /** |
| * Calling await without holding lock throws IllegalMonitorStateException |
| */ |
| public void testAwait_IllegalMonitor() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| try { |
| c.await(); |
| shouldThrow(); |
| } catch (IllegalMonitorStateException success) {} |
| } |
| |
| /** |
| * Calling signal without holding lock throws IllegalMonitorStateException |
| */ |
| public void testSignal_IllegalMonitor() { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| try { |
| c.signal(); |
| shouldThrow(); |
| } catch (IllegalMonitorStateException success) {} |
| } |
| |
| /** |
| * awaitNanos without a signal times out |
| */ |
| public void testAwaitNanos_Timeout() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| |
| lock.writeLock().lock(); |
| long t = c.awaitNanos(100); |
| assertTrue(t <= 0); |
| lock.writeLock().unlock(); |
| } |
| |
| |
| /** |
| * timed await without a signal times out |
| */ |
| public void testAwait_Timeout() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| lock.writeLock().lock(); |
| assertFalse(c.await(SHORT_DELAY_MS, MILLISECONDS)); |
| lock.writeLock().unlock(); |
| } |
| |
| /** |
| * awaitUntil without a signal times out |
| */ |
| public void testAwaitUntil_Timeout() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| lock.writeLock().lock(); |
| java.util.Date d = new java.util.Date(); |
| assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10))); |
| lock.writeLock().unlock(); |
| } |
| |
| /** |
| * await returns when signalled |
| */ |
| public void testAwait() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| c.await(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().lock(); |
| c.signal(); |
| lock.writeLock().unlock(); |
| t.join(SHORT_DELAY_MS); |
| assertFalse(t.isAlive()); |
| } |
| |
| /** A helper class for uninterruptible wait tests */ |
| class UninterruptableThread extends Thread { |
| private Lock lock; |
| private Condition c; |
| |
| public volatile boolean canAwake = false; |
| public volatile boolean interrupted = false; |
| public volatile boolean lockStarted = false; |
| |
| public UninterruptableThread(Lock lock, Condition c) { |
| this.lock = lock; |
| this.c = c; |
| } |
| |
| public synchronized void run() { |
| lock.lock(); |
| lockStarted = true; |
| |
| while (!canAwake) { |
| c.awaitUninterruptibly(); |
| } |
| |
| interrupted = isInterrupted(); |
| lock.unlock(); |
| } |
| } |
| |
| /** |
| * awaitUninterruptibly doesn't abort on interrupt |
| */ |
| public void testAwaitUninterruptibly() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| UninterruptableThread thread = new UninterruptableThread(lock.writeLock(), c); |
| |
| thread.start(); |
| |
| while (!thread.lockStarted) { |
| Thread.sleep(100); |
| } |
| |
| lock.writeLock().lock(); |
| try { |
| thread.interrupt(); |
| thread.canAwake = true; |
| c.signal(); |
| } finally { |
| lock.writeLock().unlock(); |
| } |
| |
| thread.join(); |
| assertTrue(thread.interrupted); |
| assertFalse(thread.isAlive()); |
| } |
| |
| /** |
| * await is interruptible |
| */ |
| public void testAwait_Interrupt() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| Thread t = new Thread(new CheckedInterruptedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| c.await(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.interrupt(); |
| t.join(SHORT_DELAY_MS); |
| assertFalse(t.isAlive()); |
| } |
| |
| /** |
| * awaitNanos is interruptible |
| */ |
| public void testAwaitNanos_Interrupt() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| Thread t = new Thread(new CheckedInterruptedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| c.awaitNanos(MILLISECONDS.toNanos(LONG_DELAY_MS)); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.interrupt(); |
| t.join(SHORT_DELAY_MS); |
| assertFalse(t.isAlive()); |
| } |
| |
| /** |
| * awaitUntil is interruptible |
| */ |
| public void testAwaitUntil_Interrupt() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| Thread t = new Thread(new CheckedInterruptedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| java.util.Date d = new java.util.Date(); |
| c.awaitUntil(new java.util.Date(d.getTime() + 10000)); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t.interrupt(); |
| t.join(SHORT_DELAY_MS); |
| assertFalse(t.isAlive()); |
| } |
| |
| /** |
| * signalAll wakes up all threads |
| */ |
| public void testSignalAll() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| c.await(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| c.await(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t1.start(); |
| t2.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().lock(); |
| c.signalAll(); |
| lock.writeLock().unlock(); |
| t1.join(SHORT_DELAY_MS); |
| t2.join(SHORT_DELAY_MS); |
| assertFalse(t1.isAlive()); |
| assertFalse(t2.isAlive()); |
| } |
| |
| /** |
| * A serialized lock deserializes as unlocked |
| */ |
| public void testSerialization() throws Exception { |
| ReentrantReadWriteLock l = new ReentrantReadWriteLock(); |
| l.readLock().lock(); |
| l.readLock().unlock(); |
| |
| ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); |
| ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); |
| out.writeObject(l); |
| out.close(); |
| |
| ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); |
| ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); |
| ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject(); |
| r.readLock().lock(); |
| r.readLock().unlock(); |
| } |
| |
| /** |
| * hasQueuedThreads reports whether there are waiting threads |
| */ |
| public void testhasQueuedThreads() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| Thread t1 = new Thread(new InterruptedLockRunnable(lock)); |
| Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); |
| assertFalse(lock.hasQueuedThreads()); |
| lock.writeLock().lock(); |
| t1.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertTrue(lock.hasQueuedThreads()); |
| t2.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertTrue(lock.hasQueuedThreads()); |
| t1.interrupt(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertTrue(lock.hasQueuedThreads()); |
| lock.writeLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertFalse(lock.hasQueuedThreads()); |
| t1.join(); |
| t2.join(); |
| } |
| |
| /** |
| * hasQueuedThread(null) throws NPE |
| */ |
| public void testHasQueuedThreadNPE() { |
| final ReentrantReadWriteLock sync = new ReentrantReadWriteLock(); |
| try { |
| sync.hasQueuedThread(null); |
| shouldThrow(); |
| } catch (NullPointerException success) {} |
| } |
| |
| /** |
| * hasQueuedThread reports whether a thread is queued. |
| */ |
| public void testHasQueuedThread() throws InterruptedException { |
| final ReentrantReadWriteLock sync = new ReentrantReadWriteLock(); |
| Thread t1 = new Thread(new InterruptedLockRunnable(sync)); |
| Thread t2 = new Thread(new InterruptibleLockRunnable(sync)); |
| assertFalse(sync.hasQueuedThread(t1)); |
| assertFalse(sync.hasQueuedThread(t2)); |
| sync.writeLock().lock(); |
| t1.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertTrue(sync.hasQueuedThread(t1)); |
| t2.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertTrue(sync.hasQueuedThread(t1)); |
| assertTrue(sync.hasQueuedThread(t2)); |
| t1.interrupt(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertFalse(sync.hasQueuedThread(t1)); |
| assertTrue(sync.hasQueuedThread(t2)); |
| sync.writeLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertFalse(sync.hasQueuedThread(t1)); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertFalse(sync.hasQueuedThread(t2)); |
| t1.join(); |
| t2.join(); |
| } |
| |
| |
| /** |
| * getQueueLength reports number of waiting threads |
| */ |
| public void testGetQueueLength() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| Thread t1 = new Thread(new InterruptedLockRunnable(lock)); |
| Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); |
| assertEquals(0, lock.getQueueLength()); |
| lock.writeLock().lock(); |
| t1.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertEquals(1, lock.getQueueLength()); |
| t2.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertEquals(2, lock.getQueueLength()); |
| t1.interrupt(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertEquals(1, lock.getQueueLength()); |
| lock.writeLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertEquals(0, lock.getQueueLength()); |
| t1.join(); |
| t2.join(); |
| } |
| |
| /** |
| * getQueuedThreads includes waiting threads |
| */ |
| public void testGetQueuedThreads() throws InterruptedException { |
| final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); |
| Thread t1 = new Thread(new InterruptedLockRunnable(lock)); |
| Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); |
| assertTrue(lock.getQueuedThreads().isEmpty()); |
| lock.writeLock().lock(); |
| assertTrue(lock.getQueuedThreads().isEmpty()); |
| t1.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertTrue(lock.getQueuedThreads().contains(t1)); |
| t2.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertTrue(lock.getQueuedThreads().contains(t1)); |
| assertTrue(lock.getQueuedThreads().contains(t2)); |
| t1.interrupt(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertFalse(lock.getQueuedThreads().contains(t1)); |
| assertTrue(lock.getQueuedThreads().contains(t2)); |
| lock.writeLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| assertTrue(lock.getQueuedThreads().isEmpty()); |
| t1.join(); |
| t2.join(); |
| } |
| |
| /** |
| * hasWaiters throws NPE if null |
| */ |
| public void testHasWaitersNPE() { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| try { |
| lock.hasWaiters(null); |
| shouldThrow(); |
| } catch (NullPointerException success) {} |
| } |
| |
| /** |
| * getWaitQueueLength throws NPE if null |
| */ |
| public void testGetWaitQueueLengthNPE() { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| try { |
| lock.getWaitQueueLength(null); |
| shouldThrow(); |
| } catch (NullPointerException success) {} |
| } |
| |
| |
| /** |
| * getWaitingThreads throws NPE if null |
| */ |
| public void testGetWaitingThreadsNPE() { |
| final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); |
| try { |
| lock.getWaitingThreads(null); |
| shouldThrow(); |
| } catch (NullPointerException success) {} |
| } |
| |
| /** |
| * hasWaiters throws IAE if not owned |
| */ |
| public void testHasWaitersIAE() { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(); |
| try { |
| lock2.hasWaiters(c); |
| shouldThrow(); |
| } catch (IllegalArgumentException success) {} |
| } |
| |
| /** |
| * hasWaiters throws IMSE if not locked |
| */ |
| public void testHasWaitersIMSE() { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| try { |
| lock.hasWaiters(c); |
| shouldThrow(); |
| } catch (IllegalMonitorStateException success) {} |
| } |
| |
| |
| /** |
| * getWaitQueueLength throws IAE if not owned |
| */ |
| public void testGetWaitQueueLengthIAE() { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(); |
| try { |
| lock2.getWaitQueueLength(c); |
| shouldThrow(); |
| } catch (IllegalArgumentException success) {} |
| } |
| |
| /** |
| * getWaitQueueLength throws IMSE if not locked |
| */ |
| public void testGetWaitQueueLengthIMSE() { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| try { |
| lock.getWaitQueueLength(c); |
| shouldThrow(); |
| } catch (IllegalMonitorStateException success) {} |
| } |
| |
| |
| /** |
| * getWaitingThreads throws IAE if not owned |
| */ |
| public void testGetWaitingThreadsIAE() { |
| final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock(); |
| try { |
| lock2.getWaitingThreads(c); |
| shouldThrow(); |
| } catch (IllegalArgumentException success) {} |
| } |
| |
| /** |
| * getWaitingThreads throws IMSE if not locked |
| */ |
| public void testGetWaitingThreadsIMSE() { |
| final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| try { |
| lock.getWaitingThreads(c); |
| shouldThrow(); |
| } catch (IllegalMonitorStateException success) {} |
| } |
| |
| |
| /** |
| * hasWaiters returns true when a thread is waiting, else false |
| */ |
| public void testHasWaiters() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| threadAssertFalse(lock.hasWaiters(c)); |
| threadAssertEquals(0, lock.getWaitQueueLength(c)); |
| c.await(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().lock(); |
| assertTrue(lock.hasWaiters(c)); |
| assertEquals(1, lock.getWaitQueueLength(c)); |
| c.signal(); |
| lock.writeLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().lock(); |
| assertFalse(lock.hasWaiters(c)); |
| assertEquals(0, lock.getWaitQueueLength(c)); |
| lock.writeLock().unlock(); |
| t.join(SHORT_DELAY_MS); |
| assertFalse(t.isAlive()); |
| } |
| |
| /** |
| * getWaitQueueLength returns number of waiting threads |
| */ |
| public void testGetWaitQueueLength() throws InterruptedException { |
| final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| Thread t = new Thread(new CheckedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| threadAssertFalse(lock.hasWaiters(c)); |
| threadAssertEquals(0, lock.getWaitQueueLength(c)); |
| c.await(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| t.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().lock(); |
| assertTrue(lock.hasWaiters(c)); |
| assertEquals(1, lock.getWaitQueueLength(c)); |
| c.signal(); |
| lock.writeLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().lock(); |
| assertFalse(lock.hasWaiters(c)); |
| assertEquals(0, lock.getWaitQueueLength(c)); |
| lock.writeLock().unlock(); |
| t.join(SHORT_DELAY_MS); |
| assertFalse(t.isAlive()); |
| } |
| |
| |
| /** |
| * getWaitingThreads returns only and all waiting threads |
| */ |
| public void testGetWaitingThreads() throws InterruptedException { |
| final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(); |
| final Condition c = lock.writeLock().newCondition(); |
| Thread t1 = new Thread(new CheckedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| threadAssertTrue(lock.getWaitingThreads(c).isEmpty()); |
| c.await(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| Thread t2 = new Thread(new CheckedRunnable() { |
| public void realRun() throws InterruptedException { |
| lock.writeLock().lock(); |
| threadAssertFalse(lock.getWaitingThreads(c).isEmpty()); |
| c.await(); |
| lock.writeLock().unlock(); |
| }}); |
| |
| lock.writeLock().lock(); |
| assertTrue(lock.getWaitingThreads(c).isEmpty()); |
| lock.writeLock().unlock(); |
| t1.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| t2.start(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().lock(); |
| assertTrue(lock.hasWaiters(c)); |
| assertTrue(lock.getWaitingThreads(c).contains(t1)); |
| assertTrue(lock.getWaitingThreads(c).contains(t2)); |
| c.signalAll(); |
| lock.writeLock().unlock(); |
| Thread.sleep(SHORT_DELAY_MS); |
| lock.writeLock().lock(); |
| assertFalse(lock.hasWaiters(c)); |
| assertTrue(lock.getWaitingThreads(c).isEmpty()); |
| lock.writeLock().unlock(); |
| t1.join(SHORT_DELAY_MS); |
| t2.join(SHORT_DELAY_MS); |
| assertFalse(t1.isAlive()); |
| assertFalse(t2.isAlive()); |
| } |
| |
| /** |
| * toString indicates current lock state |
| */ |
| public void testToString() { |
| ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| String us = lock.toString(); |
| assertTrue(us.indexOf("Write locks = 0") >= 0); |
| assertTrue(us.indexOf("Read locks = 0") >= 0); |
| lock.writeLock().lock(); |
| String ws = lock.toString(); |
| assertTrue(ws.indexOf("Write locks = 1") >= 0); |
| assertTrue(ws.indexOf("Read locks = 0") >= 0); |
| lock.writeLock().unlock(); |
| lock.readLock().lock(); |
| lock.readLock().lock(); |
| String rs = lock.toString(); |
| assertTrue(rs.indexOf("Write locks = 0") >= 0); |
| assertTrue(rs.indexOf("Read locks = 2") >= 0); |
| } |
| |
| /** |
| * readLock.toString indicates current lock state |
| */ |
| public void testReadLockToString() { |
| ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| String us = lock.readLock().toString(); |
| assertTrue(us.indexOf("Read locks = 0") >= 0); |
| lock.readLock().lock(); |
| lock.readLock().lock(); |
| String rs = lock.readLock().toString(); |
| assertTrue(rs.indexOf("Read locks = 2") >= 0); |
| } |
| |
| /** |
| * writeLock.toString indicates current lock state |
| */ |
| public void testWriteLockToString() { |
| ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
| String us = lock.writeLock().toString(); |
| assertTrue(us.indexOf("Unlocked") >= 0); |
| lock.writeLock().lock(); |
| String ls = lock.writeLock().toString(); |
| assertTrue(ls.indexOf("Locked") >= 0); |
| } |
| |
| } |