I thought these two lines would be equivalent execution wise:
val context1 = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
val context2 = newFixedThreadPoolContext(2, "Fixed")
But when I use "context2" in the code below it works as expected, but "context1" acts like a single thread.
val context1 = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
repeat(4) {
launch {
withContext(context1) {
Thread.sleep(2000)
}
}
}
context1.close()
Expected: 2 threads will execute in parallel. The code should complete in 4 seconds, because to 2 threads sleep for 2 seconds and then repeat.
Actual: Only one thread executes and the "repeat" is executed serially, which takes 8 seconds to complete.
Is this a bug?
Or what is meant by this documentation found here?
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().
After playing with the full code example:
import kotlinx.coroutines.*
import java.util.concurrent.Executors
fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")
fun main() = runBlocking {
val context1 = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
val context2 = newFixedThreadPoolContext(2, "Fixed")
repeat(4) {
launch {
withContext(context1) {
log("Start sleep $it")
Thread.sleep(2000)
log("Finished sleep $it")
}
}
}
// context1.close()
}
I discovered the problem is with the "context1.close()". If I comment out the "context1.close()" it works correctly. My guess is that the "launch" calls aren't blocking, so the "context1.close()" gets executed before the "withContext" executes on the other threads. I would have assumed that would cause an error, but it appears to just make it a single thread.