* T1 reads data - 20
* </ol>
*/
public void testReadUncommitted() throws Throwable {
final LockStrategy s=new LockStrategyReadUncommitted();
final FIFOSemaphore sem=new MyFIFOSemaphore(1);
final CyclicBarrier barrier=new CyclicBarrier(2);
Thread t1=new Thread("t1") {
Sync lock=null;
public void run() {
try {
sem.acquire(); // we're first to the semaphore
// log("waiting on barrier");
barrier.barrier(); // wait until t2 joins us
// log("passed barrier");
lock=s.readLock();
lock.attempt(TIMEOUT);
log("1st read: value is " + value);
assertEquals(10, value);
sem.release(); // give t2 time to make the modification
TestingUtil.sleepThread(100);
sem.acquire(); // to read the uncommitted modification by t2
log("2nd read: value is " + value + "; we should see t2's uncommitted change (20)");
assertEquals(20, value); // we're seeing the modification by t2 before t2 committed (a.k.a. released the lock)
sem.release();
TestingUtil.sleepThread(100);
sem.acquire(); // to read the committed change by t2
log("3rd read: value is still " + value + "; we should see t2's committed change");
assertEquals(20, value);
}
catch(Throwable ex) {
t1_ex=ex;
}
finally {
if(lock != null)
lock.release();
sem.release();
}
}
};
Thread t2=new Thread("t2") {
Sync lock=null;
public void run() {
try {
TestingUtil.sleepThread(100);
barrier.barrier();
sem.acquire();
lock=s.writeLock();
lock.attempt(TIMEOUT);
log("changing value from " + value + " to 20");
value=20;
sem.release(); // now t1 can read the uncommitted modification
TestingUtil.sleepThread(100);
sem.acquire(); // to release the lock
log("committing the TX");
lock.release();
}
catch(Throwable ex) {
t2_ex=ex;
}
finally {
if(lock != null)
lock.release();
sem.release();
}
}
};
t1.start();