/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.concurrency;
-import junit.framework.Assert;
import junit.framework.TestCase;
-
/**
* Testing the read-write lock class. Note: in case of problems, test cases
* could hang.
- *
+ *
* @see ReadWriteLock
*/
public class ReadWriteLockTest extends TestCase {
- /**
- *
- */
- private static final int HALF_SECOND = 500;
- /**
- *
- */
- private static final int ONE_SECOND = 1000;
- /**
- *
- */
- private static final int TWO_SECONDS = 2000;
- private ReadWriteLock _lock;
- private int _nReaders;
- private int _nWriters;
+ private static final int HALF_SECOND = 100;
+
+ private static final int ONE_SECOND = 200;
+
+ private static final int TWO_SECONDS = 400;
+ private ReadWriteLock lock;
+ private int nReaders;
+ private int nWriters;
/**
* Constructor for ReadWriteLockTest.
- *
+ *
* @param aName
*/
public ReadWriteLockTest(String aName) {
}
private synchronized int getReaderCount() {
- return _nReaders;
+ return nReaders;
}
private synchronized int getWriterCount() {
- return _nWriters;
+ return nWriters;
}
synchronized void incrementReaderCount() {
- _nReaders++;
+ nReaders++;
}
synchronized void incrementWriterCount() {
- _nWriters++;
+ nWriters++;
}
synchronized void decrementReaderCount() {
- _nReaders--;
+ nReaders--;
}
synchronized void decrementWriterCount() {
- _nWriters--;
+ nWriters--;
}
/*
*/
protected void setUp() throws Exception {
super.setUp();
- _lock = new ReadWriteLock();
+ lock = new ReadWriteLock();
}
/*
* @see TestCase#tearDown()
*/
protected void tearDown() throws Exception {
- _lock = null;
+ lock = null;
super.tearDown();
}
* Acquire and release a read lock.
*/
public void testRead() {
- _lock.acquireRead();
- _lock.releaseRead();
+ lock.acquireRead();
+ lock.releaseRead();
}
/**
* Acquire and release a write lock.
*/
public void testWrite() {
- _lock.acquireWrite();
- _lock.releaseWrite();
+ lock.acquireWrite();
+ lock.releaseWrite();
}
/**
* Verify concurrent access by multiple readers is possible.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testMultipleReaders() throws InterruptedException {
- Runnable runnable = new ReadLocker(_lock, this, TWO_SECONDS);
+ Runnable runnable = new ReadLocker(lock, this, TWO_SECONDS);
- Thread t1 = new Thread(runnable);
+ Thread t1 = new Thread(runnable);
t1.start();
Thread t2 = new Thread(runnable);
/**
* Verify that only one writer at a time can acquire the write lock.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testSingleWriter() throws InterruptedException {
- WriteLocker writer = new WriteLocker(_lock, this, ONE_SECOND);
- Thread t1 = new Thread(writer);
- Thread t2 = new Thread(writer);
+ WriteLocker writer = new WriteLocker(lock, this, ONE_SECOND);
+ Thread t1 = new Thread(writer);
+ Thread t2 = new Thread(writer);
t1.start();
t2.start();
/**
* Verify that multiple writers cannot acquire the write lock concurrently.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testMultipleWriters() throws InterruptedException {
- WriteLocker writer1 = new WriteLocker(_lock, this, HALF_SECOND + ONE_SECOND);
- WriteLocker writer2 = new WriteLocker(_lock, this, ONE_SECOND);
- Thread t1 = new Thread(writer1);
- Thread t2 = new Thread(writer2);
+ WriteLocker writer1 = new WriteLocker(lock, this, HALF_SECOND +
+ ONE_SECOND);
+ WriteLocker writer2 = new WriteLocker(lock, this, ONE_SECOND);
+ Thread t1 = new Thread(writer1);
+ Thread t2 = new Thread(writer2);
t1.start();
Thread.sleep(HALF_SECOND);
Thread.sleep(ONE_SECOND);
// at t = 2, the second writer still must have
- // a lock.
+ // a lock.
assertTrue(getWriterCount() == 1);
t1.join();
t2.join();
}
/**
- * Verify that after the first reader acquires a lock, a subsequent writer
+ * Verify that after the first reader acquires a lock, a subsequent writer
* can only acquire the lock after the reader has released it.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReadWrite1() throws InterruptedException {
- ReadLocker readLocker = new ReadLocker(_lock, this, TWO_SECONDS);
- Thread t1 = new Thread(readLocker);
- WriteLocker writeLocker = new WriteLocker(_lock, this, TWO_SECONDS);
- Thread t2 = new Thread(writeLocker);
+ ReadLocker readLocker = new ReadLocker(lock, this, TWO_SECONDS);
+ Thread t1 = new Thread(readLocker);
+ WriteLocker writeLocker = new WriteLocker(lock, this, TWO_SECONDS);
+ Thread t2 = new Thread(writeLocker);
t1.start(); // acquire read lock
Thread.sleep(HALF_SECOND);
Thread.sleep(HALF_SECOND);
// 1 second underway, reader still holding the
- // lock so write lock cannot be acquired.
+ // lock so write lock cannot be acquired.
assertTrue(getReaderCount() == 1);
assertTrue(getWriterCount() == 0);
Thread.sleep(ONE_SECOND + HALF_SECOND);
- // 2.5 seconds underway, read lock released and
- // write lock must be acquired.
+ // 2.5 seconds underway, read lock released and
+ // write lock must be acquired.
assertTrue("Wrong no. of readers: " + getReaderCount(),
getReaderCount() == 0);
assertTrue(getWriterCount() == 1);
/**
* Verify that when multiple readers have acquired a read lock, the writer
* can only acquire the lock after all readers have released it.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReadWrite2() throws InterruptedException {
- ReadLocker readLocker1 = new ReadLocker(_lock, this, TWO_SECONDS + HALF_SECOND);
- ReadLocker readLocker2 = new ReadLocker(_lock, this, TWO_SECONDS + HALF_SECOND);
- Thread t1 = new Thread(readLocker1);
- Thread t2 = new Thread(readLocker2);
- WriteLocker writeLocker = new WriteLocker(_lock, this, TWO_SECONDS);
- Thread t3 = new Thread(writeLocker);
+ ReadLocker readLocker1 = new ReadLocker(lock, this, TWO_SECONDS +
+ HALF_SECOND);
+ ReadLocker readLocker2 = new ReadLocker(lock, this, TWO_SECONDS +
+ HALF_SECOND);
+ Thread t1 = new Thread(readLocker1);
+ Thread t2 = new Thread(readLocker2);
+ WriteLocker writeLocker = new WriteLocker(lock, this, TWO_SECONDS);
+ Thread t3 = new Thread(writeLocker);
t1.start(); // acquire read lock [0, 2.5]
Thread.sleep(ONE_SECOND);
Thread.sleep(HALF_SECOND);
// t = 1.5
assertTrue(getReaderCount() == 2);
- t3.start(); // write lock
+ t3.start(); // write lock
Thread.sleep(HALF_SECOND);
- // 2 seconds,
+ // 2 seconds,
assertTrue(getReaderCount() == 2);
assertTrue(getWriterCount() == 0);
Thread.sleep(ONE_SECOND);
assertTrue(getWriterCount() == 0);
Thread.sleep(ONE_SECOND);
- // 4 seconds underway, write lock must have
- // been acquired.
+ // 4 seconds underway, write lock must have
+ // been acquired.
assertTrue(getReaderCount() == 0);
assertTrue(getWriterCount() == 1);
}
/**
- * Verify that after a writer acquires a lock, a subsequent reader can
- * only acquire the lock after the writer has released it.
- *
- * @throws InterruptedException May not occur.
+ * Verify that after a writer acquires a lock, a subsequent reader can only
+ * acquire the lock after the writer has released it.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReadWrite3() throws InterruptedException {
- ReadLocker readLocker = new ReadLocker(_lock, this, TWO_SECONDS);
- Thread t1 = new Thread(readLocker);
- WriteLocker writeLocker = new WriteLocker(_lock, this, TWO_SECONDS);
- Thread t2 = new Thread(writeLocker);
+ ReadLocker readLocker = new ReadLocker(lock, this, TWO_SECONDS);
+ Thread t1 = new Thread(readLocker);
+ WriteLocker writeLocker = new WriteLocker(lock, this, TWO_SECONDS);
+ Thread t2 = new Thread(writeLocker);
t2.start(); // acquire write lock
Thread.sleep(HALF_SECOND);
Thread.sleep(HALF_SECOND);
// 1 second underway, writer still holding the
- // lock so read lock cannot be acquired.
+ // lock so read lock cannot be acquired.
assertTrue(getWriterCount() == 1);
assertTrue(getReaderCount() == 0);
Thread.sleep(ONE_SECOND + HALF_SECOND);
- // 2.5 seconds underway, write lock released and
- // read lock must be acquired.
+ // 2.5 seconds underway, write lock released and
+ // read lock must be acquired.
assertTrue("Wrong no. of writers: " + getReaderCount(),
getWriterCount() == 0);
assertTrue(getReaderCount() == 1);
}
/*
- * The following test cases are for testing whether or not
- * the read write lock checks the locking correctly.
- * Strictly speaking, these checks wouldn't be necessary
- * because it involves the contract of the ReadWriteLock which
- * must be obeyed by users of the ReadWriteLock. Nevertheless,
- * this is tested anyway to be absolutely sure.
+ * The following test cases are for testing whether or not the read write
+ * lock checks the locking correctly. Strictly speaking, these checks
+ * wouldn't be necessary because it involves the contract of the
+ * ReadWriteLock which must be obeyed by users of the ReadWriteLock.
+ * Nevertheless, this is tested anyway to be absolutely sure.
*/
/**
- * Acquire a read lock from one thread, release it from another. Verify
- * that a RuntimeException is thrown.
- *
- * @throws InterruptedException May not occur.
+ * Acquire a read lock from one thread, release it from another. Verify that
+ * a RuntimeException is thrown.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReleaseReadFromWrongThread() throws InterruptedException {
Thread t1 = null;
try {
t1 = new Thread(new Runnable() {
- public void run() {
- ReadWriteLockTest.this._lock.acquireRead();
- }
- });
+ public void run() {
+ ReadWriteLockTest.this.lock.acquireRead();
+ }
+ });
t1.start();
Thread.sleep(ONE_SECOND); // wait until thread is started
- _lock.releaseRead(); // release lock from wrong thread.
+ lock.releaseRead(); // release lock from wrong thread.
} catch (RuntimeException e) {
return; // ok
} finally {
/**
* Acquire a write lock from one thread, release it from another. Verify
* that a RuntimeException is thrown.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReleaseWriteFromWrongThread() throws InterruptedException {
Thread t1 = null;
try {
t1 = new Thread(new Runnable() {
- public void run() {
- ReadWriteLockTest.this._lock.acquireWrite();
- }
- });
+ public void run() {
+ ReadWriteLockTest.this.lock.acquireWrite();
+ }
+ });
t1.start();
Thread.sleep(ONE_SECOND); // wait until thread is started
- _lock.releaseWrite(); // release lock from wrong thread.
+ lock.releaseWrite(); // release lock from wrong thread.
} catch (RuntimeException e) {
return; // ok
} finally {
}
/**
- * Try to acquire a read lock multiple times. Verify that a
- * RuntimeException is thrown.
+ * Try to acquire a read lock multiple times. Verify that a RuntimeException
+ * is thrown.
*/
public void testAcquireReadTwice() {
try {
- _lock.acquireRead();
- _lock.acquireRead();
+ lock.acquireRead();
+ lock.acquireRead();
} catch (RuntimeException e) {
// ok
return;
*/
public void testAcquireWriteTwice() {
try {
- _lock.acquireWrite();
- _lock.acquireWrite();
+ lock.acquireWrite();
+ lock.acquireWrite();
} catch (RuntimeException e) {
return; // ok
}
*/
public void testAcquireReadFollowedByWrite() {
try {
- _lock.acquireRead();
- _lock.acquireWrite();
+ lock.acquireRead();
+ lock.acquireWrite();
} catch (RuntimeException e) {
return; // ok
}
*/
public void testAcquireWriteFollowedByRead() {
try {
- _lock.acquireWrite();
- _lock.acquireRead();
+ lock.acquireWrite();
+ lock.acquireRead();
} catch (RuntimeException e) {
return; // ok
}
*/
public void testAcquireReadFollowedByReleaseaWrite() {
try {
- _lock.acquireRead();
- _lock.releaseWrite();
+ lock.acquireRead();
+ lock.releaseWrite();
} catch (RuntimeException e) {
return; // ok
}
*/
public void testAcquireWriteFollowedByReleaseRead() {
try {
- _lock.acquireWrite();
- _lock.releaseRead();
+ lock.acquireWrite();
+ lock.releaseRead();
} catch (RuntimeException e) {
return; // ok
}
}
}
-
/**
- * ReadLocker acquires a read lock and performs a callback when the lock as
- * been acquired, sleeps for a designated amount of time, releases the read
- * lock, and performs a callback after the lock has been released.
+ * ReadLocker acquires a read lock and performs a callback when the lock as been
+ * acquired, sleeps for a designated amount of time, releases the read lock, and
+ * performs a callback after the lock has been released.
*/
class ReadLocker implements Runnable {
- private ReadWriteLock _lock;
- private ReadWriteLockTest _lockTest;
- private int _sleepTime;
+ private ReadWriteLock lock;
+ private ReadWriteLockTest lockTest;
+ private int sleepTime;
public ReadLocker(ReadWriteLock aLock, ReadWriteLockTest aLockTest,
int aSleepTime) {
- _lock = aLock;
- _lockTest = aLockTest;
- _sleepTime = aSleepTime;
+ lock = aLock;
+ lockTest = aLockTest;
+ sleepTime = aSleepTime;
}
public void run() {
- _lock.acquireRead();
- _lockTest.incrementReaderCount();
+ lock.acquireRead();
+ lockTest.incrementReaderCount();
try {
- Thread.sleep(_sleepTime);
+ Thread.sleep(sleepTime);
} catch (InterruptedException e) {
- Assert.fail("ReadLocker thread was interrupted."
- + Thread.currentThread());
+ throw new RuntimeException("ReadLocker thread was interrupted." +
+ Thread.currentThread());
}
- _lock.releaseRead();
- _lockTest.decrementReaderCount();
+ lock.releaseRead();
+ lockTest.decrementReaderCount();
}
}
-
/**
- * WriteLocker acquires a write lock and performs a callback when the lock as
+ * WriteLocker acquires a write lock and performs a callback when the lock as
* been acquired, sleeps for a designated amount of time, releases the write
* lock, and performs a callback after the lock has been released.
*/
class WriteLocker implements Runnable {
- private ReadWriteLock _lock;
- private ReadWriteLockTest _lockTest;
- private int _sleepTime;
+ private ReadWriteLock lock;
+ private ReadWriteLockTest lockTest;
+ private int sleepTime;
public WriteLocker(ReadWriteLock aLock, ReadWriteLockTest aLockTest,
int aSleepTime) {
- _lock = aLock;
- _lockTest = aLockTest;
- _sleepTime = aSleepTime;
+ lock = aLock;
+ lockTest = aLockTest;
+ sleepTime = aSleepTime;
}
public void run() {
- _lock.acquireWrite();
- _lockTest.incrementWriterCount();
+ lock.acquireWrite();
+ lockTest.incrementWriterCount();
try {
- Thread.sleep(_sleepTime);
+ Thread.sleep(sleepTime);
} catch (InterruptedException e) {
- Assert.fail("WriteLocker thread was interrupted: "
- + Thread.currentThread());
+ throw new RuntimeException("WriteLocker thread was interrupted: " +
+ Thread.currentThread());
}
- _lock.releaseWrite();
- _lockTest.decrementWriterCount();
+ lock.releaseWrite();
+ lockTest.decrementWriterCount();
}
}