/* * 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/publicdomain/zero/1.0/ */ import java.util.concurrent.locks.*; class ReadHoldingWriteLock { public static void main(String[] args) throws Exception { ReadHoldingWriteLock t = new ReadHoldingWriteLock(); t.testReadAfterWriteLock(); t.testReadHoldingWriteLock(); t.testReadHoldingWriteLock2(); t.testReadHoldingWriteLockFair(); t.testReadHoldingWriteLockFair2(); } static final long SHORT_DELAY_MS = 50; static final long MEDIUM_DELAY_MS = 200; void assertTrue(boolean b) { if (!b) throw new Error(); } /** * Readlocks succeed after a writing thread unlocks */ public void testReadAfterWriteLock() throws Exception { final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); lock.writeLock().lock(); Thread t1 = new Thread(new Runnable() { public void run() { lock.readLock().lock(); lock.readLock().unlock(); } }); Thread t2 = new Thread(new Runnable() { public void run() { 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()throws Exception { 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 */ public void testReadHoldingWriteLock2() throws Exception { final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); lock.writeLock().lock(); Thread t1 = new Thread(new Runnable() { public void run() { lock.readLock().lock(); lock.readLock().unlock(); } }); Thread t2 = new Thread(new Runnable() { public void run() { 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 trylock succeeds if write locked by current thread */ public void testReadHoldingWriteLockFair() throws Exception { 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 */ public void testReadHoldingWriteLockFair2() throws Exception { final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); lock.writeLock().lock(); Thread t1 = new Thread(new Runnable() { public void run() { lock.readLock().lock(); lock.readLock().unlock(); } }); Thread t2 = new Thread(new Runnable() { public void run() { 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()); } }