package com.farsight_systems.concurrent.locks.test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import com.farsight_systems.concurrent.atomic.AtomicBoolean;
import com.farsight_systems.concurrent.locks.HoldState;
import com.farsight_systems.concurrent.locks.ReenterableReadWriteLock;
import com.farsight_systems.concurrent.locks.Latch;
import com.farsight_systems.concurrent.locks.LatchCondition;
import com.farsight_systems.concurrent.locks.LatchStandard;
/**
* A simple test class.
*
* @author Jeffrey
* @version 2010-MAY-10a JDS
*/
public class TestLocksAndLatches
{
/**
* The value for a Fair lock.
*/
public static final boolean fair = true;
/**
* The value for an Unfair lock.
*/
public static final boolean unfair = !fair;
/**
* The value for allowing upgrade from solitary read-only to read-write.
*/
public static final boolean allowUpgrade = true;
/**
* The value for disallowing upgrade from solitary read-only to read-write.
*/
public static final boolean disallowUpgrade = !allowUpgrade;
/**
* The value for read-only state.
*/
public static final HoldState READ_ONLY = HoldState.READ_ONLY;
/**
* The value for read-write state.
*/
public static final HoldState READ_WRITE = HoldState.READ_WRITE;
/**
* The requestor 1.
*/
public static final long requestor_1 = 1L;
/**
* The requestor 2.
*/
public static final long requestor_2 = 2L;
/**
* The requestor 3.
*/
public static final long requestor_3 = 3L;
/**
* A tester class for a Latch.
*/
public static final class TesterLatch
implements Runnable
{
private volatile boolean started;
private long requestor;
private Latch latch;
private LatchCondition latchCondition;
private AtomicBoolean atomicBoolean;
private TesterLatch(final long theRequestor, final Latch theLatch, final LatchCondition theLatchCondition, final AtomicBoolean theAtomicBoolean)
{
super();
requestor = theRequestor;
latch = theLatch;
latchCondition = theLatchCondition;
atomicBoolean = theAtomicBoolean;
}
private synchronized void handshake()
{
started = true;
notify();
}
private void perform()
{
latch.acquire(requestor,READ_ONLY);
try
{
while(!atomicBoolean.get())
{
latchCondition.await(requestor);
}
}
catch(Exception ex)
{
ex.printStackTrace();
ex = null;
}
finally
{
latch.release(requestor);
}
}
public void run()
{
handshake();
perform();
}
}
/**
* A tester class for a Lock.
*/
public static final class TesterLock
implements Runnable
{
private volatile boolean started;
private Lock lock;
private Condition condition;
private AtomicBoolean atomicBoolean;
private TesterLock(final Lock theLock, final Condition theCondition, final AtomicBoolean theAtomicBoolean)
{
super();
lock = theLock;
condition = theCondition;
atomicBoolean = theAtomicBoolean;
}
private synchronized void handshake()
{
started = true;
notify();
}
private void perform()
{
lock.lock();
try
{
while(!atomicBoolean.get())
{
condition.await();
}
}
catch(Exception ex)
{
ex.printStackTrace();
ex = null;
}
finally
{
lock.unlock();
}
condition = null;
lock = null;
}
public void run()
{
handshake();
perform();
}
}
/**
* Create and start a test thread.
*
* @param theRequestor The 64-bit requestor identifier.
* @param theLatch The Latch instance.
* @param theLatchCondition The LatchCondition instance.
* @param theAtomicBoolean The AtomicBoolean instance.
*
* @return The Thread instance.
*/
private static Thread tester(final long theRequestor, final Latch theLatch, final LatchCondition theLatchCondition, final AtomicBoolean theAtomicBoolean)
{
Thread thread;
TesterLatch tester;
tester = new TesterLatch(theRequestor,theLatch,theLatchCondition,theAtomicBoolean);
thread = new Thread(tester);
synchronized(tester)
{
thread.start();
do
{
try
{
tester.wait();
}
catch(InterruptedException ex)
{
ex.printStackTrace();
ex = null;
}
} while(!tester.started);
}
tester = null;
return thread;
}
/**
* Create and start a test thread.
*
* @param theLock The Lock instance.
* @param theCondition The Condition instance.
* @param theAtomicBoolean The AtomicBoolean instance.
*
* @return The Thread instance.
*/
private static Thread tester(final Lock theLock, final Condition theCondition, final AtomicBoolean theAtomicBoolean)
{
Thread thread;
TesterLock tester;
tester = new TesterLock(theLock,theCondition,theAtomicBoolean);
thread = new Thread(tester);
synchronized(tester)
{
thread.start();
do
{
try
{
tester.wait();
}
catch(InterruptedException ex)
{
ex.printStackTrace();
ex = null;
}
} while(!tester.started);
}
tester = null;
return thread;
}
/**
* Test latch.
*/
public static void latches()
{
Latch latch;
LatchCondition latchCondition;
AtomicBoolean atomicBoolean;
Thread thread1;
Thread thread2;
latch = LatchStandard.createLatch(fair, disallowUpgrade);
latchCondition = latch.createLatchCondition();
atomicBoolean = new AtomicBoolean(false);
latch.acquire(requestor_1,READ_ONLY);
try
{
thread1 = tester(requestor_2,latch,latchCondition,atomicBoolean);
thread2 = tester(requestor_3,latch,latchCondition,atomicBoolean);
}
finally
{
latch.release(requestor_1);
}
latch.acquire(requestor_1,READ_WRITE);
try
{
atomicBoolean.set(true);
latchCondition.signalAll(requestor_1);
}
finally
{
latch.release(requestor_1);
}
try
{
thread1.join();
thread2.join();
}
catch(InterruptedException ex)
{
ex.printStackTrace();
ex = null;
}
thread1 = null;
thread2 = null;
atomicBoolean = null;
latchCondition = null;
latch = null;
}
/**
* Test locks.
*/
public static void locks()
{
ReadWriteLock readWriteLock;
Lock readLock;
Lock writeLock;
Condition condition;
AtomicBoolean atomicBoolean;
Thread thread1;
Thread thread2;
readWriteLock = new ReenterableReadWriteLock(unfair);
readLock = readWriteLock.readLock();
writeLock = readWriteLock.writeLock();
condition = writeLock.newCondition();
atomicBoolean = new AtomicBoolean(false);
readLock.lock();
try
{
thread1 = tester(readLock,condition,atomicBoolean);
thread2 = tester(writeLock,condition,atomicBoolean);
}
finally
{
readLock.unlock();
}
writeLock.lock();
try
{
atomicBoolean.set(true);
condition.signalAll();
}
finally
{
readLock.unlock();
}
try
{
thread1.join();
thread2.join();
}
catch(InterruptedException ex)
{
ex.printStackTrace();
ex = null;
}
thread1 = null;
thread2 = null;
atomicBoolean = null;
condition = null;
writeLock = null;
readLock = null;
}
/**
* Main entry point.
*
* @param args The start-up parameters.
*/
public static void main(final String[] args)
{
latches();
locks();
}
private TestLocksAndLatches()
{
super();
}
}
|