Hi,
I came across this thread when googling and was wondering what the correct way to do this is in 2020, using Kotlin 1.3.72, kotlinx.coroutines 1.3.8 and IntelliJ IDEA 2020.2? This does not compile:
val processContext = newFixedThreadPoolContext(5, "asdf")
suspend fun execute(processBuilder: ProcessBuilder): Int = run(processContext) {
Thread.sleep(1000) // simulating a slow command
processBuilder.start().waitFor()
}
It complains on the run
:
e: /Users/simon/code/test-kotlin-coroutines/src/main/kotlin/test/kotlin/coroutines/App.kt: (19, 60): Type inference failed: inline fun <R> run(block: () -> R): R
cannot be applied to
(ExecutorCoroutineDispatcher)
e: /Users/simon/code/test-kotlin-coroutines/src/main/kotlin/test/kotlin/coroutines/App.kt: (19, 64): Type mismatch: inferred type is ExecutorCoroutineDispatcher but () -> Int was expected
e: /Users/simon/code/test-kotlin-coroutines/src/main/kotlin/test/kotlin/coroutines/App.kt: (19, 80): Too many arguments for public inline fun <R> run(block: () -> R): R defined in kotlin
When instead using runBlocking
, it seems to work; however, IntelliJ IDEA warns for “Inappropriate blocking method call”. runInterruptible
is the other thing I could find, and seems to work fine – so is that what I should use?
IntelliJ IDEA also warns about newFixedThreadPoolContext
:
NOTE: This API will be replaced in the future. A different API to create thread-limited thread pools that is based on a shared thread-pool and does not require the resulting dispatcher to be explicitly closed will be provided, thus avoiding potential thread leaks and also significantly improving performance, due to coroutine-oriented scheduling policy and thread-switch minimization. See issue #261 for details. If you need a completely separate thread-pool with scheduling policy that is based on the standard JDK executors, use the following expression: Executors.newFixedThreadPool().asCoroutineDispatcher(). See Executor.asCoroutineDispatcher for details.
I tried this:
val ctx = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
fun main(args: Array<String>) {
GlobalScope.launch { // launch a new coroutine in background and continue
runInterruptible(ctx) {
Thread.sleep(1000L)
}
println("World!")
}
println("Hello,")
Thread.sleep(2000L)
}
However, the effect then was that the program never exited, I guess some thread was kept alive.