In Java when main thread exits, all user threads (non-deamon threads) will keep running until they finish their job.
I have a simple program which print a counter from 1 to 5 to console.
Java version:
fun main(args: Array<String>) {
println("Main start")
countWithThread()
println("Main end")
}
fun countWithThread() {
Thread(Runnable {
for (i in 1..5) {
println("${Thread.currentThread().name} count $i")
Thread.sleep(10)
}
}).start()
}
Output:
Main start
Main end
Thread-0 count 1
Thread-0 count 2
Thread-0 count 3
Thread-0 count 4
Thread-0 count 5
Process finished with exit code 0
Kotlin version:
fun main(args: Array<String>) {
println("Main start")
countWithCoroutine()
println("Main end")
}
fun countWithCoroutine() {
launch(CommonPool) {
for (i in 1..5) {
println("${Thread.currentThread().name} count $i")
delay(10)
}
}
}
Output:
Main start
Main end
Process finished with exit code 0
As you can see, when main thread exits, the code in the coroutine does not run anymore. It seems Kotlin terminate all coroutines under the hood.
Can anyone tell me what exactly happen with coroutines when main thread exits?
A process can exit at any time when a thread calls the exit subroutine. Similarly, a thread can exit at any time by calling the pthread_exit subroutine. Calling the exit subroutine terminates the entire process, including all its threads.
Main thread is cooperative, it allows scheduling of tasks and coroutines just use this feature.
Coroutines is our recommended solution for asynchronous programming on Android. Noteworthy features include the following: Lightweight: You can run many coroutines on a single thread due to support for suspension, which doesn't block the thread where the coroutine is running.
You can suspend execution and do work on other threads while using a different mechanism for scheduling and managing that work. However, this version of kotlinx. coroutines cannot change threads on its own.
Coroutines on their own aren't "running" in a way that the JVM would know about. They're nothing but objects on the heap.
However, the coroutine context does have a say in when it will allow the JVM to terminate. Create your own:
val threadPool = Executors.newFixedThreadPool(4)
val dispatcher = threadPool.asCoroutineDispatcher()
Now if you use it instead of CommonPool
:
launch(dispatcher) { ... }
you'll find the JVM doesn't die at all, even when all the tasks are done. It will exit only when you explicitly say
threadPool.shutdown()
Note, however, that executor.shutdown()
doesn't behave towards coroutines the same as towards the "classic" tasks you submit to it. The executor will ensure all the submitted tasks are done before shutting down, but it has no account of the suspended coroutines.
Coroutines are terminated when the main thread finishes execution and the process/JVM instance dies, they are like daemon threads. See this section in the official coroutine guide for reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With