package au.gov.ga.earthsci.worldwind.common.util; import static org.junit.Assert.assertTrue; import java.lang.Thread.State; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ThreadFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * Unit tests for the {@link LenientReadWriteLock} */ public class LenientReadWriteLockTest { private LenientReadWriteLock classToBeTested; private List<Thread> threads = new ArrayList<Thread>(); private ThreadFactory threadFactory = new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread result= new Thread(r); result.setDaemon(true); threads.add(result); return result; }; }; @Before public void setup() { classToBeTested = new LenientReadWriteLock(); } @After @SuppressWarnings("deprecation") public void teardown() { // Destroy all threads for (Thread thread : threads) { thread.stop(); } threads.clear(); } @Test public void testMultipleReadsOk() throws Exception { Thread reader1 = threadFactory.newThread(new ReadeTask()); Thread reader2 = threadFactory.newThread(new ReadeTask()); reader1.start(); Thread.sleep(100); reader2.start(); Thread.sleep(100); assertTrue(reader1.getState() != State.WAITING); assertTrue(reader2.getState() != State.WAITING); } @Test public void testReadBlocksWriteSeparateThread() throws Exception { Thread reader = threadFactory.newThread(new ReadeTask()); Thread writer = threadFactory.newThread(new WriteTask()); reader.start(); Thread.sleep(100); writer.start(); Thread.sleep(100); assertTrue(reader.getState() != State.WAITING); assertTrue(writer.getState() == State.WAITING); } @Test public void testWriteBlocksReadSeparateThread() throws Exception { Thread reader = threadFactory.newThread(new ReadeTask()); Thread writer = threadFactory.newThread(new WriteTask()); writer.start(); Thread.sleep(100); reader.start(); Thread.sleep(100); assertTrue(reader.getState() == State.WAITING); assertTrue(writer.getState() != State.WAITING); } @Test public void testWriteBlocksWriteSeparateThread() throws Exception { Thread writer1 = threadFactory.newThread(new WriteTask()); Thread writer2 = threadFactory.newThread(new WriteTask()); writer2.start(); Thread.sleep(100); writer1.start(); Thread.sleep(100); assertTrue(writer1.getState() == State.WAITING); assertTrue(writer2.getState() != State.WAITING); } @Test public void testWriteAllowsWriteSameThread() throws Exception { Thread thread = threadFactory.newThread(new WriteWriteTask()); thread.start(); Thread.sleep(100); assertTrue(thread.getState() != State.WAITING); } @Test public void testWriteAllowsReadSameThread() throws Exception { Thread thread = threadFactory.newThread(new WriteReadTask()); thread.start(); Thread.sleep(100); assertTrue(thread.getState() != State.WAITING); } @Test public void testReadAllowsWriteSameThread() throws Exception { Thread thread = threadFactory.newThread(new ReadWriteTask()); thread.start(); Thread.sleep(100); assertTrue(thread.getState() != State.WAITING); } @Test public void testReadAllowsReadSameThread() throws Exception { Thread thread = threadFactory.newThread(new ReadReadTask()); thread.start(); Thread.sleep(100); assertTrue(thread.getState() != State.WAITING); } private class ReadeTask implements Runnable { @Override public void run() { classToBeTested.readLock().lock(); try { Thread.sleep(500); } catch (InterruptedException e) { classToBeTested.readLock().unlock(); } } } private class WriteTask implements Runnable { @Override public void run() { classToBeTested.writeLock().lock(); try { Thread.sleep(500); } catch (InterruptedException e) { classToBeTested.writeLock().unlock(); } } } private class WriteWriteTask implements Runnable { @Override public void run() { classToBeTested.writeLock().lock(); classToBeTested.writeLock().lock(); try { Thread.sleep(500); } catch (InterruptedException e) { classToBeTested.writeLock().unlock(); } } } private class WriteReadTask implements Runnable { @Override public void run() { classToBeTested.writeLock().lock(); classToBeTested.readLock().lock(); try { Thread.sleep(500); } catch (InterruptedException e) { classToBeTested.writeLock().unlock(); } } } private class ReadReadTask implements Runnable { @Override public void run() { classToBeTested.writeLock().lock(); classToBeTested.readLock().lock(); try { Thread.sleep(500); } catch (InterruptedException e) { classToBeTested.writeLock().unlock(); } } } private class ReadWriteTask implements Runnable { @Override public void run() { classToBeTested.writeLock().lock(); classToBeTested.readLock().lock(); try { Thread.sleep(500); } catch (InterruptedException e) { classToBeTested.writeLock().unlock(); } } } }