Search code examples
kotlinkotlinx.coroutines

Shut down the underlying Executor of ExecutorCoroutineDispatcher


I repeatedly find myself writing code as this:

val threadPoolExecutor = Executors.newCachedThreadPool()
val threadPool = threadPool.asCoroutineDispatcher()

What I really need is just the coroutine dispatcher so I can write stuff like

launch(threadPool) { ... }

or

withContext(threadPool) { ... }

and I need the threadPoolExecutor just to be able to shut it down on cleanup. Is there a way to use the coroutine dispatcher instance to shut it down instead?


Solution

  • At the moment this is no out-of-the box solution, but you can write your own asCoroutineDispatcher extension to provide such an experience:

    abstract class CloseableCoroutineDispatcher : CoroutineDispatcher(), Closeable
    
    fun ExecutorService.asCoroutineDispatcher(): CloseableCoroutineDispatcher =
        object : CloseableCoroutineDispatcher() {
            val delegate = (this@asCoroutineDispatcher as Executor).asCoroutineDispatcher()
            override fun isDispatchNeeded(context: CoroutineContext): Boolean = delegate.isDispatchNeeded(context)
            override fun dispatch(context: CoroutineContext, block: Runnable) = delegate.dispatch(context, block)
            override fun close() = shutdown()
        }
    

    This question had lead to the following change request: https://github.com/Kotlin/kotlinx.coroutines/issues/278