https://kotlinlang.org logo
#coroutines
Title
# coroutines
a

Aaron Stacy

01/03/2020, 3:49 AM
Why does this program not terminate?
suspend fun main() = withContext(Executors.newSingleThreadExecutor().asCoroutineDispatcher()) {}
Even if I call cancel() from within the withContext block, I see an exception logged, but the program just hangs.
o

octylFractal

01/03/2020, 3:52 AM
probably the thread never gets spun down, and it's not a daemon thread, so JVM can't exit
👍 1
d

Dico

01/03/2020, 11:08 AM
Read API docs for newSingleThreadExecutor about whether thread is daemon or not
👍 1
t

Thiyagu

01/03/2020, 12:32 PM
a

Aaron Stacy

01/03/2020, 2:39 PM
Thanks @Thiyagu!
close()
worked
👍 1
Interestingly, the thread is created with a default thread factory, which according to https://github.com/openjdk-mirror/jdk7u-jdk/blob/f4d80957e89a19a29bb9f9807d2a28351ed7f7df/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java#L103 suggests it's not a daemon thread.
OK, confusingly, if I supply my own factory that creates a daemon thread, it exists without extra action. This aligns with that
ThreadPoolExecutor
javadoc saying that by default, the thread is not a daemon, but it's surprising because I'd think a "daemon" would need to be explicitly exited.
d

Dico

01/03/2020, 2:48 PM
No it's the other way around.
a

Aaron Stacy

01/03/2020, 2:49 PM
Ah, https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setDaemon(boolean) welp there you go. Thank you everyone for your help!
t

Thiyagu

01/03/2020, 2:56 PM
You can always provide your
ThreadFactory
implementation to the executor.
l

louiscad

01/04/2020, 6:11 PM
The code from the original snippet should be replaced by
fun main() = runBlocking { ... }
to it doesn't waste a bunch of threads (namely, the JVM main thread and the threads from Dispatchers.Default).
a

Aaron Stacy

01/16/2020, 2:56 PM
Ah cool, thank you Louis!
4 Views