Is it possible to throw exception if incoming request can't be handled?
So, I have some fixed thread pool:
private val executor: ThreadPoolExecutor = Executors.newFixedThreadPool(4) as ThreadPoolExecutor
And I don't want requests go to thread queue if can't be handled, I just want to throw exception.
I'm trying to check activeCount and throw exception if is greater than max pool size but it's not working just like I want.
private fun checkPoolSize() {
if (executor.activeCount >= 4) {
throw RuntimeException("Request can't be handled. ")
}
}
One solution for this is to use a queue of capacity 0 and java.util.concurrent.ThreadPoolExecutor.AbortPolicy
as a RejectedExecutionHandler
.
The static methods in Executors
do not expose the full set of parameters you want for this, so you will need to instantiate a ThreadPoolExecutor
directly. In your case, you could use the following:
new ThreadPoolExecutor(4, /* Core pool size */
4, /* Max pool size */
0, TimeUnit.SECONDS, /* Core th. keep-alive */
new MyQueue<Runnable>(0), /* No queueing allowed */
Executors.defaultThreadFactory(), /* default */
new AbortPolicy()) /* throws when all core threads busy */
A few notes:
Executors.newFixedThreadPool(4)
.Executors.defaultThreadFactory()
is the default thread factory, same as when using Executors.newFixedThreadPool(4)
.MyQueue
is an implementation of BlockingQueue
which accepts 0 as a capacity (i.e. which can only be empty. This is of course not a queue but implementing this allows to seamlessly integrating with the ThreadPoolExecutor
provided by the JDK.). Further consideration:
With such fine-tuning of your thread pool, beware that the throughput will be limited. Here, considering 4 threads and an average latency L
in seconds for the tasks submitted to the thread pool, the average throughput allowed by this configuration is 4/L
tasks/second.