I thought that calling a "suspend" function from coroutine context using launch
makes the call asynchronous. But in the example below I see that 2 invocations of placeOrder
method are not running in the same thread one after another.
What is my mistake?
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.File
fun main() = runBlocking {
t("1")
launch {
t("2")
placeOrder("C:\\Users")
t("3")
}
launch {
t("12")
placeOrder("C:\\Program Files")
t("13")
}
t("4")
}
fun t(s: String) {
val currentThread = Thread.currentThread()
println(s + ": " + currentThread.name + " " + currentThread.id)
}
suspend fun placeOrder(d:String): String {
t("placeOrder $d")
val user = createUser(d) // asynchronous call to user service
val order = createOrder(user) // asynchronous call to order service
t("placeOrder $d finished")
return order
}
suspend fun createUser(d:String): String {
t("createUser $d")
val toString = File(d).walk().map {
it.length()
}.sum().toString()
t("createUser $d finished")
return toString
}
suspend fun createOrder(user: String): String {
t("createOrder $user")
val toString = File("C:\\User").walk().map {
it.length()
}.sum().toString()
t("createOrder $user finished")
return toString
}
Output:
1: main 1
4: main 1
2: main 1
placeOrder C:\Users: main 1
createUser C:\Users: main 1
createUser C:\Users finished: main 1
createOrder 1094020270277: main 1
createOrder 1094020270277 finished: main 1
placeOrder C:\Users finished: main 1
3: main 1
12: main 1
placeOrder C:\Program Files: main 1
createUser C:\Program Files: main 1
createUser C:\Program Files finished: main 1
createOrder 5651227104: main 1
createOrder 5651227104 finished: main 1
placeOrder C:\Program Files finished: main 1
13: main 1
by default the methods are executed sequentially one after another. N.B:- codes are sequentially executed within a coroutine by default.
Coroutines and/or generators can be used to implement cooperative functions. Instead of being run on kernel threads and scheduled by the operating system, they run in a single thread until they yield or finish, yielding to other functions as determined by the programmer.
Kotlin Coroutines Creating too many threads can actually make an application underperform in some situations; threads are objects which impose overhead during object allocation and garbage collection. To overcome these issues, Kotlin introduced a new way of writing asynchronous, non-blocking code; the Coroutine.
coroutines , which can be used for iOS, supports usage only in a single thread. You cannot send work to other threads by changing a dispatcher. For Kotlin 1.7.
Instead of writing suspendable IO, you wrote blocking IO:
File(d).walk().map {
it.length()
}
Your functions never actually suspend and instead they block the single thread associated with their runBlocking
dispatcher.
You gave your coroutines no opportunity to execute concurrently.
If you applied withContext(IO) { ... }
around the above code, you'd get concurrency, but of the plain-old Java type, several threads being blocked in IO operations together.
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