Created
June 27, 2024 14:10
-
-
Save dumptruckman/d33044d23d8d3248393ea1528ea26375 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A custom ThreadPoolTaskExecutor based on this SO answer https://stackoverflow.com/a/24493856. | |
* | |
* The main distinction of this executor is that it will not wait for the queue to be full before scaling up the number | |
* of threads in the pool. Instead, it will scale up the number of threads in the pool (up to the maximum) as soon as | |
* a new task is submitted and no idle threads are available to run it. Then, once the number of threads reaches the | |
* maximum, it will start to queue tasks. | |
*/ | |
class ImmediatelyScalingThreadPoolTaskExecutor : ThreadPoolTaskExecutor() { | |
override fun createQueue(queueCapacity: Int): BlockingQueue<Runnable> { | |
return object : LinkedTransferQueue<Runnable>() { | |
override fun offer(e: Runnable): Boolean { | |
// tryTransfer will return false if no thread is available to run the task which will cause the thread | |
// pool to either spawn a new thread or reject the task. If the task is rejected, the custom | |
// RejectedExecutionHandler will put the task into the queue | |
return tryTransfer(e) | |
} | |
} | |
} | |
override fun initializeExecutor(threadFactory: ThreadFactory, ignore: RejectedExecutionHandler): ExecutorService { | |
val rejectedExecutionHandler = RejectedExecutionHandler { r, executor -> | |
try { | |
executor.queue.put(r) | |
} catch (e: InterruptedException) { | |
Thread.currentThread().interrupt() | |
} | |
} | |
return super.initializeExecutor(threadFactory, rejectedExecutionHandler) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment