Skip to content

Instantly share code, notes, and snippets.

@ylegall
Last active January 12, 2018 18:31
Show Gist options
  • Save ylegall/a09a24aab92c6b9ec6f187abb6f2559d to your computer and use it in GitHub Desktop.
Save ylegall/a09a24aab92c6b9ec6f187abb6f2559d to your computer and use it in GitHub Desktop.
RejectedExecutionException example
import java.time.Duration;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
*
*/
public class ThreadPoolTest {
private static final int IDLE_THREADS = 5;
private static final int MAX_THREADS = 5;
private static final int QUEUE_SIZE = 3;
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(MAX_THREADS);
final TaskFactory taskFactory = new TaskFactory(latch);
final ExecutorService executor = new ThreadPoolExecutor(
IDLE_THREADS,
MAX_THREADS,
500L, // max idle duration, but since IDLE_THREADS == maxPoolSize, thread count will not decrease
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(QUEUE_SIZE),
new DebugThreadFactory()
);
// initially send n tasks to fill pool to MAX_THREADS:
System.err.println("initializing core threads");
for (int i = 0; i < MAX_THREADS; ++i) {
executor.execute(taskFactory.getTaskWithDuration(Duration.ofSeconds(1L)));
}
// wait for all initial tasks to finish so that all threads are idle
System.err.println("waiting for initial tasks to complete");
latch.await();
System.err.println("done waiting");
// after the core threads have been initialized, all requests will go into the queue.
// therefore a burst of (queueSize + 1) requests will likely cause a RejectedExecutionException
System.err.println("expecting a RejectedExecutionException...");
for (int i = 0; i < QUEUE_SIZE + 1; ++i) {
executor.execute(taskFactory.getTaskWithDuration(Duration.ofSeconds(1L)));
}
executor.shutdown();
executor.awaitTermination(1L, TimeUnit.DAYS);
}
}
/**
*
*/
class TaskFactory
{
private final CountDownLatch latch;
private final AtomicInteger taskId = new AtomicInteger(1);
TaskFactory(final CountDownLatch latch) {
this.latch = latch;
}
public Runnable getTaskWithDuration(final Duration duration) {
return () -> {
final int id = taskId.getAndIncrement();
try {
Thread.sleep(duration.toMillis());
latch.countDown();
System.err.println(" * finished task " + id);
} catch (InterruptedException e) {
System.err.println(e.getMessage());
}
};
}
}
/**
*
*/
class DebugThreadFactory implements ThreadFactory
{
private int threadId = 1;
@Override
public Thread newThread(final Runnable runnable) {
System.err.println(" * creating thread " + threadId);
final Thread thread = new Thread(runnable, "t-" + threadId);
threadId++;
thread.setDaemon(true);
return thread;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment