package org.limewire.concurrent;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import junit.framework.Test;
import org.limewire.util.BaseTestCase;
public class ThreadExecutorTest extends BaseTestCase {
public ThreadExecutorTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(ThreadExecutorTest.class);
}
public void testThreadStarts() throws Exception {
Runner r1 = new Runner();
ThreadExecutor.startThread(r1, "Name");
assertTrue(r1.getRanLatch().await(100, TimeUnit.MILLISECONDS));
assertEquals("Name", r1.getName());
}
public void testReuseThreads() throws Exception {
Runner r1 = new Runner();
ThreadExecutor.startThread(r1, "Name1");
assertTrue(r1.getRanLatch().await(100, TimeUnit.MILLISECONDS));
assertEquals("Name1", r1.getName());
Thread.sleep(100); // let the thread rename happen.
assertEquals("IdleThread", r1.getThread().getName());
Runner r2 = new Runner();
ThreadExecutor.startThread(r2, "Name2");
assertTrue(r2.getRanLatch().await(100, TimeUnit.MILLISECONDS));
assertSame(r1.getThread(), r2.getThread());
assertEquals("Name2", r2.getName());
}
public void testThreadLingers() throws Exception {
Runner r1 = new Runner();
ThreadExecutor.startThread(r1, "Name");
assertTrue(r1.getRanLatch().await(100, TimeUnit.MILLISECONDS));
Thread thread = r1.getThread();
Thread.sleep(100); // let the thread rename happen.
assertEquals("IdleThread", r1.getThread().getName());
assertTrue(thread.isAlive());
Thread.sleep(3500);
assertTrue(thread.isAlive());
Thread.sleep(2000);
assertFalse(thread.isAlive());
assertEquals("IdleThread", r1.getThread().getName());
}
public void testManyThreadsAtOnce() throws Exception {
CountDownLatch runLatch = new CountDownLatch(1);
Runner r1 = new Runner(runLatch);
Runner r2 = new Runner(runLatch);
ThreadExecutor.startThread(r1, "Name1");
ThreadExecutor.startThread(r2, "Name2");
assertTrue(r1.getStartedLatch().await(100, TimeUnit.MILLISECONDS));
assertTrue(r2.getStartedLatch().await(100, TimeUnit.MILLISECONDS));
assertFalse(r1.getRanLatch().await(100, TimeUnit.MILLISECONDS));
assertFalse(r2.getRanLatch().await(100, TimeUnit.MILLISECONDS));
assertNotSame(r1.getThread(), r2.getThread());
assertEquals("Name1", r1.getName());
assertEquals("Name2", r2.getName());
runLatch.countDown();
assertTrue(r1.getRanLatch().await(100, TimeUnit.MILLISECONDS));
assertTrue(r2.getRanLatch().await(100, TimeUnit.MILLISECONDS));
}
public void testDaemonThread() throws Exception {
Runner r1 = new Runner();
ThreadExecutor.startThread(r1, "Name");
assertTrue(r1.getRanLatch().await(100, TimeUnit.MILLISECONDS));
assertTrue(r1.getThread().isDaemon());
}
private static class Runner implements Runnable {
private volatile Thread thread;
private volatile String name;
private final CountDownLatch startedLatch = new CountDownLatch(1);
private final CountDownLatch ranLatch = new CountDownLatch(1);
private final CountDownLatch runLatch;
public Runner() {
runLatch = null;
}
public Runner(CountDownLatch runLatch) {
this.runLatch = runLatch;
}
public void run() {
thread = Thread.currentThread();
name = thread.getName();
startedLatch.countDown();
if(runLatch != null) {
try {
if(!runLatch.await(10, TimeUnit.SECONDS))
fail("never got notified!");
} catch(InterruptedException ignore) {}
}
ranLatch.countDown();
}
public CountDownLatch getRanLatch() {
return ranLatch;
}
public CountDownLatch getStartedLatch() {
return startedLatch;
}
public Thread getThread() {
return thread;
}
public String getName() {
return name;
}
}
}