Recently I was refreshing myself on kotlin coroutines, as I had worked with them before but never fulled grasped all the ins and outs of coroutines, and I decided to make some notes while I was reading through the docs (https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html).
I figured they would be helpful to other kotlin developers. Note that these are quick notes I jotted down and isn't a fully grammatical tutorial-esque article.
Summary
Coroutines are light-weight threads
CoroutineScope - Used to build coroutines, contains CoroutineContext
Scope Types:
- GlobalScope - Lifetime of the new coroutine is limited only by the lifetime of the whole application
- CoroutineScope - Is destroyed after all launched children are completed
- MainScope - Scope for UI applications and uses Dispatchers.Main
CoroutineContext - A collection of various elements. Contains Job and CoroutineDispatcher
CoroutineDispatcher - Determines the thread(s) to use
Dispatcher types:
- Unconfined - I’m working in thread main (appropriate for coroutines which neither consume CPU time nor update any shared data (like UI) confined to a specific thread)
- Default - I'm working in thread DefaultDispatcher-worker-1
- newSingleThreadContext - I’m working in thread MyOwnThread
- main runBlocking - I’m working in thread main
- newSingleThreadContext() - Creates new thread, can be used to switch between using withContext
Launch
- Launch is a coroutine builder that returns a Job
- Launch inherits the context from the scope it’s launched from
- Customizing Launch:
- Can pass variables between threads using
asContextElement
- Can name Coroutines using
CoroutineName
- Can pass variables between threads using
Async
- Async is like launch, but returns a Deferred (i.e. future)
- Async
CoroutineStart.LAZY
only starts when await is called
Cancellation
- Jobs can be cancelled or call join, which works like pthread_join
- Coroutine cancellation is cooperative, meaning if the coroutine isn’t checking if it’s cancelled then it won’t be cancelled
-
SupervisorJob
is a job where cancellation is only propagated downwards -
withTimeout
creates a timeout for the coroutines (throwsTimeoutCancellationException
) - When cancelled:
- Job throws an exception which can be handled with finally or catch (
CancellationException
) - All child coroutines are cancelled as well
- Job throws an exception which can be handled with finally or catch (
Suspend
- Suspend can be used inside coroutines, but can also use other suspending functions
- If a coroutine builder is inside suspend function a CoroutineScope needs to be added as well
Blocking
-
runBlocking
runs a new coroutine and blocks the current thread, interruptible until it’s completion - Delay is non blocking
Flow
- Flow is an asynchronous stream of values
. Uses
Emit
andCollect
to send and collect data - Flow runs in the context that is provided the collector
- The code inside a flow isn’t run until the flow is collected
- Flows can be cancelled with
withTimeoutOrNull
- Useful functions:
- transform - customize data, such as emitting a header first
- take - only take a certain amount of the flow
- flowOn - change the context of preceding code
- zip - combine multiple flows
- catch - catch any exceptions of preceding code
- onCompletion - perform any final tasks after the flow is done
Channel
- Similar to a blocking queue, a way to transfer values between coroutines
- Uses
send
andreceive
for normal values,produce
andconsume
for streams - Channels can be closed to indicate no more elements are coming
Actor
- Actor is an entity that can receive a class of messages using sealed classes. Meaning a consumer that takes in sealed classes
Let me know if I got anything wrong, or if I missed anything. Hope this helps!
Top comments (0)