costly to create • Limited by processor core • Coroutine • It is a ‘concept’ to allow execution of program to be suspended and resumed • Live inside thread -> a single Thread can have many coroutines • Mostly, languages have their own implementation • goroutine • Kotlin coroutines
computation, conceptually similar to a thread, in the sense that it takes a block of code to run and has a similar life-cycle, it is created and started, but it is not bound to any particular thread. It may suspend its execution in one thread and resume in another one. Moreover, like a future or promise, it may complete with some result or exception.”
that a coroutine is running • Similar to RxJava’s Schedulers • CoroutineContext • Contain set of elements that represent a coroutine, such as • Dispatcher • Job, a component that hold coroutine execution. We can doing cancellation of coroutine via Job • CoroutineScope • Hold coroutines Context and Dispatcher • Scoping coroutines execution, to make it easier with cancellation
builders • Dispatchers.IO • Designed for I/O task, such as networking, files • Dispatchers.Main • Confined execution in Main Thread (UI) • Dispatchers.Unconfined • Using the same thread by the caller, and might switch to another thread when have corresponding suspended function
just launch an execution and don’t care about the return value • Kind of similar to RxJava Completable • async • Launch execution and await for the return value • Kind of similar to RxJava Single • runBlocking • Launch execution that behave like sequential process • withContext • Used to switch execution into another CoroutineContext (*Thread)
} print(“Hello, ") Thread.sleep(2_000) } // it will print // Hello, World! We need a scope to launch coroutine Without this line it will just print Hello Because that GlobalScope coroutine is running (suspended) in background
} print(“Hello, “) runBlocking { delay(2_000) } } // it will print // Hello, World Blocking coroutine To make it coroutines friendly than using Thread.sleep
return a Job object • Kind of similar with RxJava’s Disposable • Job.join() • To wait until a Job is complete • Job.cancel() • To cancel a Job execution • It will throw CancellationException, but swallowed by coroutines as default behaviour
we have many coroutines of GlobalScope. To handle join or cancel of all of them manually is error-prone. • This is might lead into potential memory leak • So, avoid using GlobalScope
println("World!") } print("Hello, ") } // it will print // Hello, World! It will launch coroutine using runBlocking’s scope It will create parent-child relation between jobs The coroutine lifecycle (cancel, join) will be handled by runBlocking’s scope
{ delay(200) println("task in runBlocking") } coroutineScope { launch { delay(500) println("task in nested launch of coroutine scope") } delay(100) println("task in coroutine scope") } println("coroutine scope is over") } // it will print // task in coroutine scope // task in runBlocking // task in nested launch of coroutine scope // coroutine scope is over It will create a new scope The new scope won’t complete until all child complete
} suspend fun world() { delay(1_000) println(“World!") } // it will print // World! // Hello, With suspend modifier we can make a function can be called inside coroutine block But will be executed sequentially