package de.invesdwin.util.concurrent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.concurrent.ThreadSafe;
import org.junit.Test;
import de.invesdwin.util.assertions.Assertions;
@ThreadSafe
public class ExecutorsTest {
private final AtomicInteger recursion = new AtomicInteger();
private volatile boolean success;
@Test
public void testSingleThreadExecutor() throws InterruptedException {
final WrappedExecutorService executor = Executors.newFixedThreadPool("testSingleThreadExecutor", 1);
for (int i = 0; i < 2; i++) {
executor.execute(new WaitingRunnable(i));
}
executor.shutdown();
executor.awaitTermination();
}
private static class WaitingRunnable implements Runnable {
private final int id;
WaitingRunnable(final int id) {
this.id = id;
}
@Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(id + ": beendet"); //SUPPRESS CHECKSTYLE single line
}
}
@Test(expected = InterruptedException.class)
public void testInterruptWithShutdownNow() throws InterruptedException {
final ExecutorService executor = Executors.newFixedThreadPool("testInterruptMitShutdownNow", 1);
final Future<Void> future = executor.submit(new Callable<Void>() {
@Override
public Void call() throws InterruptedException {
success = true;
TimeUnit.DAYS.sleep(9999);
return null;
}
});
while (!success) {
TimeUnit.MILLISECONDS.sleep(100);
}
executor.shutdownNow();
Futures.get(future);
}
@Test
public void testCached() throws InterruptedException {
final WrappedExecutorService executor = Executors.newCachedThreadPool("testCached");
executor.execute(new Runnable() {
@Override
public void run() {
success = true;
}
});
executor.shutdown();
executor.awaitTermination();
Assertions.assertThat(success).isTrue();
}
@Test
public void testExceptionWithFixedThreadPool() throws InterruptedException {
final WrappedExecutorService executor = Executors.newFixedThreadPool("testException", 1);
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("Before Exception"); //SUPPRESS CHECKSTYLE single line
throw new RuntimeException("The Exception");
}
});
executor.shutdown();
executor.awaitTermination();
}
@Test
public void testExceptionWithScheduledThreadPool() throws InterruptedException {
final WrappedExecutorService executor = Executors.newScheduledThreadPool("testException", 1);
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("Before Exception"); //SUPPRESS CHECKSTYLE single line
throw new RuntimeException("The Exception");
}
});
executor.shutdown();
executor.awaitTermination();
}
@Test
public void testSpecialWait() throws InterruptedException {
final ExecutorService executor = Executors.newFixedThreadPool("testSpecialWait", 1);
for (int i = 0; i < 3; i++) {
executor.execute(getWorker(i));
}
final Runnable spezial = getWorker(999);
Futures.submitAndWait(executor, spezial);
System.out.println("end"); //SUPPRESS CHECKSTYLE single line
}
@Test
public void testDynamic() throws InterruptedException {
final List<Runnable> tasks = new ArrayList<Runnable>();
for (int i = 0; i < 100; i++) {
tasks.add(getWorker(i));
}
final ExecutorService executor = Executors.newFixedThreadPool("testDynamic", 10);
Futures.submitAndWait(executor, tasks);
System.out.println("end"); //SUPPRESS CHECKSTYLE single line
}
// @Test
// public void testStatisch() {
// AsyncThreadPoolExecutor executor = (AsyncThreadPoolExecutor) Executors.newFixedThreadPool("testStatisch", 10);
// List<Future<?>> futures = new ArrayList<Future<?>>();
// for (int i = 1; !executor.aktiveThreadAnzahlErreicht(); i++) {
// futures.add(executor.submit(getWorker(i)));
// }
// for (Future<?> future : futures) {
// Assert.assertNull(SynchronisationUtil.get(future));
// }
// log.debug("ende");
// }
@Test
public void testRecursiveWorker() throws InterruptedException {
final int rekusionen = 100;
final WrappedExecutorService executor = Executors.newFixedThreadPool("testRecursiveWorker", 2);
final Object result = new Object();
final Future<Object> future = executor.submit(getRecursiveWorker(executor, rekusionen), result);
Assertions.assertThat(Futures.get(future)).isSameAs(result);
executor.shutdown();
executor.awaitTermination();
System.out.println("end"); //SUPPRESS CHECKSTYLE single line
}
@Test
public void testCancel() throws InterruptedException {
final WrappedExecutorService executor = Executors.newFixedThreadPool("testCancel", 1);
final Future<?> futureRunning = executor.submit(getWorker(1));
final Future<?> futureDelayed = executor.submit(getWorker(2));
TimeUnit.MILLISECONDS.sleep(10);
Assertions.assertThat(futureDelayed.cancel(false)).isTrue();
Assertions.assertThat(futureRunning.cancel(true)).isTrue();
TimeUnit.MILLISECONDS.sleep(100);
executor.shutdown();
executor.awaitTermination();
}
private Runnable getWorker(final int i) {
return new Thread() {
@Override
public void run() {
try {
sleep(100);
System.out.println("end worker " + i); //SUPPRESS CHECKSTYLE single line
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
};
}
private Runnable getRecursiveWorker(final ExecutorService executor, final int maxRecursion) {
return new Runnable() {
@Override
public void run() {
final int curRecursion = recursion.incrementAndGet();
if (curRecursion != maxRecursion) {
final Runnable worker = getRecursiveWorker(executor, maxRecursion);
executor.execute(worker);
}
System.out.println("end worker recursionlevel " + curRecursion); //SUPPRESS CHECKSTYLE single line
}
};
}
}