package aQute.lib.concurrentinit;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import org.junit.Assert;
import org.junit.Test;
public class ConcurrentInitializeTest extends Assert {
final static Executor executor = Executors.newCachedThreadPool();
@Test
public void testSimple() throws Exception {
ConcurrentInitialize<String> ci = new ConcurrentInitialize<String>() {
@Override
public String create() throws Exception {
return "foo";
}
};
assertEquals("foo", ci.get());
}
@Test
public void testConcurrent() throws InterruptedException {
final Semaphore result = new Semaphore(0);
final Semaphore onCreate = new Semaphore(0);
final ConcurrentInitialize<String> ci = new ConcurrentInitialize<String>() {
@Override
public String create() throws Exception {
onCreate.acquire();
return "foo";
}
};
final Thread threads [] = new Thread[10];
for (int i = 0; i < 10; i++) {
final int j = i;
executor.execute(new Runnable() {
@Override
public void run() {
threads[j] = Thread.currentThread();
try {
ci.get();
result.release();
} catch (Exception e) {
// cant happen
}
}
});
}
// First wait so that we can verify that nobody can
// continue until we allow it
Thread.sleep(100);
assertEquals(0, result.availablePermits());
// allow the creator to pass
onCreate.release(1); // only 1 can create
// Check the results
result.acquire(10);
}
@Test(expected = Exception.class)
public void testExceptionForFirstCall() throws Exception {
ConcurrentInitialize<String> ci = new ConcurrentInitialize<String>() {
@Override
public String create() throws Exception {
throw new Exception();
}
};
ci.get();
}
@Test(expected = Exception.class)
public void testExceptionForFurtherCalls() throws Exception {
ConcurrentInitialize<String> ci = new ConcurrentInitialize<String>() {
@Override
public String create() throws Exception {
throw new Exception();
}
};
try {
ci.get();
} catch (Exception e) {
// ignore
}
ci.get();
}
}