I use a pretty much default newCachedThreadPool but I want to limit the thread creation so I create ExecutorService like this
new ThreadPoolExecutor(0, Runtime.getRuntime().availableProcessors() * 2,
60L, TimeUnit.SECONDS,
new SynchronousQueue<>());
After reading javadocs I expected it to work in way that when I submit Runnable, taskExecutor blocks when offering SynchronousQueue a new task, untill there is available thread to execute it and then a handoff occurs. Unfortunately after reaching the thread pool capacity and when all threads are busy, taskExecutor throws RejectedExecutionException. I know I can pass a RejectedExecutionHandler that will block, but I'm just suprise that it seems I have to. Can someone explain if it is really working as intended or am I doing something wrong?
This code reproduces my case:
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(0, Runtime.getRuntime().availableProcessors() * 2,
60L, TimeUnit.SECONDS,
new SynchronousQueue<>());
while (true) {
executor.submit(() -> System.out.println("bla"));
}
}
This is in accordance with ThreadPoolExecutor API:
• If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.
As to why SynchronousQueue does not block - because ThreadPoolExecutor uses queue.offer() instead of put()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With