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

Pablo

02/01/2021, 9:43 AM
Hello guys is there any explanation for
suspend fun
for dummies? I mean, if you would have to explain what is a
suspend
for someone that is completely new on this world of coroutines what would be your answer?
l

Lukas Sztefek

02/01/2021, 9:44 AM
Do you want to know more about usage or internals?
p

Pablo

02/01/2021, 9:45 AM
No, something like, suspend fun are main-safe but if you add a wrong body in the function and block the UI, something like that
I mean, suspend doesn't block the current thread but if you add wrong body to its function it could block
l

Lukas Sztefek

02/01/2021, 9:51 AM
https://medium.com/mobile-app-development-publication/understanding-suspend-function-of-coroutines-de26b070c5ed This is pretty good explanation. It also explains difference between blocking and suspending which is crucial to understand coroutines correctly.
n

Niklas Gürtler

02/01/2021, 9:54 AM
suspend basically allows the kotlin compiler to internally automagically split that function body into multiple blocks of code, where the split points are certain special functions such as delay or waiting for other coroutine's results. The individual blocks are run as whole on the specified thread/dispatcher, but inbetween those blocks anything else can be run on the thread. When e.g. the delay has elapsed, the next block of code is run as a whole. If you (wrongly) execute a blocking function that is not a suspend fun (like Thread.sleep), the kotlin compiler will not split the code block there, and the thead will actually block and can't be used by anything else.
p

Pablo

02/01/2021, 10:04 AM
@Lukas Sztefek what I see is that suspend can pause resume pause resume N times and it won't affect the funcion 2, but if function 1 gets block (for isntance Thread.Sleep()) it will block the thread and the function 2 won't stop until function 1 stop blocking
But about, suspend, what it does internally? I know suspend fun you can call them from a coroutine or other suspend fun, but more info for dummies?
@Niklas Gürtler That's a good example though, but I'd like to understand for someone that is not technical for instance, what is doing suspend under-the-hood, I mean something like, this runs in a coroutine and doesn't block the thread what is inside but if you put wrong stuff like BigInteger.findPrime(...) even if it's suspend and supsend doesn't block the current thread it would do, etc.. you got me?
n

Niklas Gürtler

02/01/2021, 10:09 AM
A suspend fun that does a big calculation will block the thread... A coroutine will only "give up" the thread at certain points such as delay that are explicitly intended to do that
p

Pablo

02/01/2021, 10:17 AM
But what I need to explain is this phrase: A suspending function is simply a function that can be paused and resumed at a later time. They can execute a long running operation and wait for it to complete without blocking.
What does it mean, that dependning of the threads or coroutines available they can do some part of the suspend method then go to another method then return to the suspended one?
n

Niklas Gürtler

02/01/2021, 10:20 AM
That's overly general... That long running operation needs to be something that is intended to be used that way, such as delay or job.wait() ... yes exactly, the threads involved execute pieces of coroutines as they become ready to execute
That's the difference to "classic" multithreading - a thread can be interrupted at any point, so that another thread can use the CPU. So even if you have multiple threads doing big calculations and just one CPU core, the OS can distribute the time (and therefore processing power) evenly among them, by forcibly interrupting them and switching between them. With multiple coroutines sharing one thread, it's different - coroutines have to voluntarily give up control to switch to other coroutines, and they don't allow you to share processing time evenly.
p

Pablo

02/01/2021, 10:29 AM
ok so in general terms a suspend fun is a function that can be paused/resumed many times until its execution is finished without blocking the thread?
n

Niklas Gürtler

02/01/2021, 10:53 AM
Yes, but the function needs to explicitly allow suspending at certain points. It can block, but it doesn't block when it's suspended
v

Vivek Sharma

02/01/2021, 10:57 AM
yes, suspend function are like normal functions only, but as they are called from a coroutine, they can suspend themselves till they process and have the result ready, and then they can resume to give the result
1

https://www.youtube.com/watch?v=ne6CD1ZhAI0&feature=emb_logo

its a video from coroutines codelab, take a look you will understand better
👀 1
p

Pablo

02/01/2021, 12:05 PM
Ok got it, i'm trying to do an example of it and wondering why this code stops the execution...
Copy code
suspend fun foo() : String {
   val bar = withContext(Dispatchers.Default) { BigInteger.probablePrime(4096,Random())}
}

fun main () {
  CoroutineScope(Dispatchers.Unconfined).launch{
print("example1")
print("example2")
print("example3")
print(foo())
print("example4")
print("example5")
print("example6")
}
}
Problem here the execution stops on example 3 and rest are not executed that's because I'm using Unconfined?
n

Niklas Gürtler

02/01/2021, 12:06 PM
execution blocks until probablePrime returns. If that takes long...
withContext
waits for the stuff inside to complete
p

Pablo

02/01/2021, 12:07 PM
I'm trying to run this block
And it says provess finished with exit code 0
and last print was example 3
n

Niklas Gürtler

02/01/2021, 12:09 PM
oh probably because the outer coroutine doesn't keep the process alive
maybe wrap the main() inside a
runBlocking
Copy code
fun main () {
  runBlocking {
  CoroutineScope(Dispatchers.Unconfined).launch{
print("example1")
print("example2")
print("example3")
print(foo())
print("example4")
print("example5")
print("example6")
}.join()
}
}
p

Pablo

02/01/2021, 12:18 PM
But what if I have more than 1 launch?
n

Niklas Gürtler

02/01/2021, 12:19 PM
Copy code
fun main () {
  runBlocking {
    coroutineScope(Dispatchers.Unconfined) {
      launch { ... }
      launch { ... }
    }
  }
}
v

Vivek Sharma

02/01/2021, 12:22 PM
Copy code
fun main() = runBlocking<Unit> {

    launch {
        for (i in 1..10){
            delay(200)
            println("I am not blocked")
        }
    }

    println(doSomething())
}

suspend fun doSomething(): String {
    println("doing something")
    delay(2000)
//    Thread.sleep(3000)
    return "something done"
}
p

Pablo

02/01/2021, 12:23 PM
@Vivek Sharma where you do this? I mean do you use a kotlin file where you can run it?
v

Vivek Sharma

02/01/2021, 12:23 PM
run this code, you can see that suspend fun here is not blocking our main thread but if you comment delay() and uncomment Thread.sleep(), you will see the difference
IntelliJ IDEA
3 Views