Java Thread Pool with a Bounded Queue
I've solved this with a Semaphore which I use to throttle tasks being submitted to the ExecutorService
.
Eg:
int threadCount = 10;
ExecutorService consumerPool = Executors.newFixedThreadPool(threadCount);
// set the permit count greater than thread count so that we
// build up a limited buffer of waiting consumers
Semaphore semaphore = new Semaphore(threadCount * 100);
for (int i = 0; i < 1000000; ++i) {
semaphore.acquire(); // this might block waiting for a permit
Runnable consumer = () -> {
try {
doSomeWork(i);
} finally {
semaphore.release(); // release a permit
}
};
consumerPool.submit(consumer);
}
When you create a ThreadPoolExecutor you can give it a bounded BlockingQueue and a RejectedExecutionHandler so you can control what happens when the limit is reached. The default behaviour is to throw a RejectedExecutionException.
You can also define you own thread factory to control the thread names and make them daemon threads.
Create a ThreadPoolexecutor and pass suitable BlockingQueue implementation in it. for e.g. you can pass in a ArrayBlockingQueue in the ThreadPoolExecutor constructor to get the desired effect.
What you want to do is new your own ExecutorService, probably using ThreadPoolExecutor. ThreadPoolExecutor has a constructor which takes a BlockingQueue and to get a bounded queue you use for example ArrayBlockingQueue properly constructed for bounding. You can also include a RejectedExecutionHandler in order to determine what to do when your queue is full, or hang on to a reference to the blocking queue and use the offer methods.
Here's a mini example:
BlockingQueue<Runnable> linkedBlockingDeque = new LinkedBlockingDeque<Runnable>(
100);
ExecutorService executorService = new ThreadPoolExecutor(1, 10, 30,
TimeUnit.SECONDS, linkedBlockingDeque,
new ThreadPoolExecutor.CallerRunsPolicy());