package org.limewire.concurrent;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.Test;
import org.limewire.util.BaseTestCase;
public class AtomicLazyReferenceTest extends BaseTestCase {
public AtomicLazyReferenceTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(AtomicLazyReferenceTest.class);
}
public void testSingleton() {
AbstractLazySingletonProvider<Object> o = new AbstractLazySingletonProvider<Object>() {
@Override
protected Object createObject() {
return new Object();
}
};
Object gotten = o.get();
assertSame(gotten, o.get());
}
public void testLaziness() {
StubAtomicLazyReference o = new StubAtomicLazyReference();
assertNull(o.obj);
Object gotten = o.get();
assertNotNull(o.obj);
assertSame(gotten, o.obj);
assertSame(gotten, o.get());
assertSame(o.get(), o.obj);
}
public void testSynchronization() throws Exception {
CountDownLatch latch = new CountDownLatch(1);
final CountDownLatch runLatch = new CountDownLatch(2);
final SwitchedAtomicLazyReference ref = new SwitchedAtomicLazyReference(latch);
ExecutorService service = ExecutorsHelper.newThreadPool("SyncTester");
Runnable r = new Runnable() {
public void run() {
runLatch.countDown();
ref.get();
}
};
assertEquals(0, ref.getCreates());
assertNull(ref.obj);
service.execute(r);
service.execute(r);
runLatch.await();
Thread.sleep(500);
latch.countDown();
Thread.sleep(500);
assertNotNull(ref.obj);
assertEquals(1, ref.getCreates());
assertSame(ref.obj, ref.get());
assertEquals(1, ref.getCreates());
}
private static class StubAtomicLazyReference extends AbstractLazySingletonProvider<Object> {
Object obj;
@Override
protected Object createObject() {
obj = new Object();
return obj;
}
}
private static class SwitchedAtomicLazyReference extends StubAtomicLazyReference {
private AtomicInteger creates = new AtomicInteger();
private final CountDownLatch latch;
public SwitchedAtomicLazyReference(CountDownLatch latch) {
this.latch = latch;
}
@Override
protected Object createObject() {
creates.getAndIncrement();
try {
latch.await();
} catch(InterruptedException failed) {
fail(failed);
}
return super.createObject();
}
public int getCreates() {
return creates.get();
}
}
}