events to the appropriate user interface widgets, including drawing events. It is also almost always the thread in which your application interacts with components from the Android UI toolkit (components from the android.widget and android.view packages)
This method is only for use in very special circumstances -- it can easily starve the message queue, cause ordering problems, or have other unexpected side-effects.
it for: computing-intensive coroutines Dispatchers.IO • Shared pool of on-demand created threads • Use it for: IO-intensive blocking operations Dispatchers.Main • Main thread • Use it for: UI operations
it for: computing-intensive coroutines Dispatchers.Unconfined • Doesn’t confine the coroutine to any specific thread • Don’t use it in code Dispatchers.IO • Shared pool of on-demand created threads • Use it for: IO-intensive blocking operations Dispatchers.Main • Main thread • Use it for: UI operations
nextPrintTime = startTime var i = 0 while (i < 5) { // computation loop, just wastes CPU // print a message twice a second if (System.currentTimeMillis() >= nextPrintTime) { println("job: I'm sleeping ${i ++ } ... ") nextPrintTime += 500L } } } delay(1300L) // delay a bit println("main: I'm tired of waiting!") job.cancelAndJoin() // cancels the job and waits for its completion println("main: Now I can quit.")
nextPrintTime = startTime var i = 0 while (isActive) { // cancellable computation loop // print a message twice a second if (System.currentTimeMillis() >= nextPrintTime) { println("job: I'm sleeping ${i ++ } ... ") nextPrintTime += 500L } } } delay(1300L) // delay a bit println("main: I'm tired of waiting!") job.cancelAndJoin() // cancels the job and waits for its completion println("main: Now I can quit.")
-> println("job: I'm sleeping $i ... ") delay(500L) } } finally { println("job: I'm running finally") } } delay(1300L) // delay a bit println("main: I'm tired of waiting!") job.cancelAndJoin() // cancels the job and waits for its completion println("main: Now I can quit.")
doing something useful here return 13 } suspend fun doSomethingUsefulTwo(): Int { delay(1000L) // pretend we are doing something useful here, too return 29 }
doSomethingUsefulOne() } val two = async { doSomethingUsefulTwo() } println("The answer is ${one.await() + two.await()}") } println("Completed in $time ms")
doSomethingUsefulOne() } val two = async { doSomethingUsefulTwo() } println("The answer is ${one.await() + two.await()}") } println("Completed in $time ms”) // The answer is 42 // Completed in 1017 ms
doSomethingUsefulOne() } val two = async { doSomethingUsefulTwo() } println("The answer is ${one.await() + two.await()}") } println("Completed in $time ms")
doSomethingUsefulOne() }.await() val two = async { doSomethingUsefulTwo() }.await() println("The answer is ${one + two}") } println("Completed in $time ms")
doSomethingUsefulOne() }.await() val two = async { doSomethingUsefulTwo() }.await() println("The answer is ${one + two}") } println("Completed in $time ms")
doSomethingUsefulOne() } val two = async { doSomethingUsefulTwo() } println("The answer is ${one.await() + two.await()}") } println("Completed in $time ms")
named the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
return all the values at once. To represent the stream of values that are being asynchronously computed, we can use a Flow<Int> type just like we would use the Sequence<Int> type for synchronously computed values
coroutine to check if the main thread is blocked launch { for (k in 1 .. 3) { println("I'm not blocked $k") delay(100) } } / / Collect the flow simple().collect { value -> println(value) } } fun simple(): Flow<Int> = flow { / / flow builder for (i in 1 . . 3) { delay(100) // pretend we are doing something useful here emit(i) / / emit next value } }
function (which returns a flow) is not marked with suspend modifier. By itself, simple() call returns quickly and does not wait for anything. The flow starts every time it is collected, that is why we see "Flow started" when we call collect again.
was collected in [CoroutineId(1), "coroutine#1":BlockingCoroutine{Active}@5511c7f8, BlockingEventLoop@2eac3323], but emission happened in [CoroutineId(1), "coroutine#1":DispatchedCoroutine{Active}@2dae0000, Dispatchers.Default]. Please refer to 'flow' documentation or use 'flowOn' instead at ...
{ value -> println(value) } } fun simple(): Flow<Int> = flow { println("Flow started") for (i in 1 .. 3) { delay(100) emit(i) } }.flowOn(Dispatchers.Default)