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

Erik

09/10/2020, 5:41 PM
The other day I came across
suspend fun main()
for the first time. Where is it documented? How does it work?
w

wasyl

09/10/2020, 6:13 PM
It’s been added some time ago already https://youtrack.jetbrains.com/issue/KT-17679. There aren’t many details in the issue but it seems like a shortcut for
fun main(args: Array<String>) = runBlocking { ... }
🚫 1
z

Zach Klippenstein (he/him) [MOD]

09/10/2020, 6:49 PM
I think the only difference is that
suspend fun main
uses the Default dispatcher
e

Erik

09/10/2020, 6:50 PM
I think it's not obvious that it uses
runBlocking
under the hood. As this is a
suspend fun
I'm blind to the coroutine scope and context, right? So it's not within my power to know and control whether or not my coroutines run blocking or are backed by many threads?
z

Zach Klippenstein (he/him) [MOD]

09/10/2020, 6:55 PM
It’s definitely not obvious. You can always use
withContext
to be explicit about that anyway though.
e

Erik

09/10/2020, 6:57 PM
So I can escape the synchrony of
runBlocking
that way? 😎 I'll have to try that some time soon
Btw, if I'd had to guess, I would have thought that it was a shorthand for
GlobalSope.launch
z

Zach Klippenstein (he/him) [MOD]

09/10/2020, 7:07 PM
So I can escape the synchrony of runBlocking that way?
Not really. Regardless of which dispatchers your coroutines are running on,
main
has to block at some point or your program will just exit immediately without running any coroutines.
☝️ 1
w

wasyl

09/10/2020, 7:28 PM
Yep, I kind of read the issue which said it should be equivalent, but clearly the implementation is different. The bytecode for such suspend main is:
Copy code
// signature ([Ljava/lang/String;Lkotlin/coroutines/Continuation<-Lkotlin/Unit;>;)Ljava/lang/Object;
// declaration:  main(java.lang.String[], kotlin.coroutines.Continuation<? super kotlin.Unit>)
public final static main([Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
Then there’s synthetic method:
Copy code
// $FF: synthetic method
public static void main(String[] var0) {
  RunSuspendKt.runSuspend(new AppKt$$$main(var0));
}
And the
RunSuspend
class uses empty coroutine context:
Copy code
private class RunSuspend : Continuation<Unit> {
    override val context: CoroutineContext
        get() = EmptyCoroutineContext
g

gildor

09/10/2020, 11:45 PM
Suspend main doesn't use runBlocking under the hood and not shortcut for GlobalScope.launch, runBlocking is not a part of stdlib, this is a library function The main difference it doesn't provide coroutine scope, but in terms of threading it should be the same as runBlocking on the main thread, it uses main thread
3 Views