blob: 58134de8eb3e1402cc3ef8a3897c97a820a71997 [file] [log] [blame] [view]
Roman Elizarov43e90112017-05-10 11:25:20 +03001<!--- INCLUDE .*/example-([a-z]+)-([0-9a-z]+)\.kt
Roman Elizarova5e653f2017-02-13 13:49:55 +03002/*
3 * Copyright 2016-2017 JetBrains s.r.o.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
Roman Elizarovf16fd272017-02-07 11:26:00 +030017
Roman Elizarova5e653f2017-02-13 13:49:55 +030018// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
19package guide.$$1.example$$2
Roman Elizarovf16fd272017-02-07 11:26:00 +030020
Roman Elizarova5e653f2017-02-13 13:49:55 +030021import kotlinx.coroutines.experimental.*
Roman Elizarovf16fd272017-02-07 11:26:00 +030022-->
Roman Elizarove8d79342017-08-29 15:21:21 +030023<!--- KNIT core/kotlinx-coroutines-core/src/test/kotlin/guide/.*\.kt -->
24<!--- TEST_OUT core/kotlinx-coroutines-core/src/test/kotlin/guide/test/GuideTest.kt
Roman Elizarov731f0ad2017-02-22 20:48:45 +030025// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
26package guide.test
27
28import org.junit.Test
29
30class GuideTest {
31-->
Roman Elizarovf16fd272017-02-07 11:26:00 +030032
Roman Elizarov7deefb82017-01-31 10:33:17 +030033# Guide to kotlinx.coroutines by example
34
35This is a short guide on core features of `kotlinx.coroutines` with a series of examples.
36
Roman Elizarov2a638922017-03-04 10:22:43 +030037## Introduction and setup
38
39Kotlin, as a language, provides only minimal low-level APIs in its standard library to enable various other
40libraries to utilize coroutines. Unlike many other languages with similar capabilities, `async` and `await`
41are not keywords in Kotlin and are not even part of its standard library.
42
Robert Hencke497d3432017-04-11 00:14:29 -040043`kotlinx.coroutines` is one such rich library. It contains a number of high-level
Roman Elizarov2a638922017-03-04 10:22:43 +030044coroutine-enabled primitives that this guide covers, including `async` and `await`.
45You need to add a dependency on `kotlinx-coroutines-core` module as explained
46[here](README.md#using-in-your-projects) to use primitives from this guide in your projects.
47
Roman Elizarov1293ccd2017-02-01 18:49:54 +030048## Table of contents
49
Roman Elizarovfa7723e2017-02-06 11:17:51 +030050<!--- TOC -->
51
Roman Elizarov1293ccd2017-02-01 18:49:54 +030052* [Coroutine basics](#coroutine-basics)
53 * [Your first coroutine](#your-first-coroutine)
54 * [Bridging blocking and non-blocking worlds](#bridging-blocking-and-non-blocking-worlds)
55 * [Waiting for a job](#waiting-for-a-job)
56 * [Extract function refactoring](#extract-function-refactoring)
57 * [Coroutines ARE light-weight](#coroutines-are-light-weight)
58 * [Coroutines are like daemon threads](#coroutines-are-like-daemon-threads)
59* [Cancellation and timeouts](#cancellation-and-timeouts)
60 * [Cancelling coroutine execution](#cancelling-coroutine-execution)
61 * [Cancellation is cooperative](#cancellation-is-cooperative)
62 * [Making computation code cancellable](#making-computation-code-cancellable)
63 * [Closing resources with finally](#closing-resources-with-finally)
64 * [Run non-cancellable block](#run-non-cancellable-block)
65 * [Timeout](#timeout)
66* [Composing suspending functions](#composing-suspending-functions)
67 * [Sequential by default](#sequential-by-default)
Roman Elizarov32d95322017-02-09 15:57:31 +030068 * [Concurrent using async](#concurrent-using-async)
69 * [Lazily started async](#lazily-started-async)
70 * [Async-style functions](#async-style-functions)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +030071* [Coroutine context and dispatchers](#coroutine-context-and-dispatchers)
Roman Elizarovfa7723e2017-02-06 11:17:51 +030072 * [Dispatchers and threads](#dispatchers-and-threads)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +030073 * [Unconfined vs confined dispatcher](#unconfined-vs-confined-dispatcher)
74 * [Debugging coroutines and threads](#debugging-coroutines-and-threads)
75 * [Jumping between threads](#jumping-between-threads)
76 * [Job in the context](#job-in-the-context)
77 * [Children of a coroutine](#children-of-a-coroutine)
78 * [Combining contexts](#combining-contexts)
79 * [Naming coroutines for debugging](#naming-coroutines-for-debugging)
Roman Elizarov2fd7cb32017-02-11 23:18:59 +030080 * [Cancellation via explicit job](#cancellation-via-explicit-job)
Roman Elizarovb7721cf2017-02-03 19:23:08 +030081* [Channels](#channels)
82 * [Channel basics](#channel-basics)
83 * [Closing and iteration over channels](#closing-and-iteration-over-channels)
84 * [Building channel producers](#building-channel-producers)
85 * [Pipelines](#pipelines)
86 * [Prime numbers with pipeline](#prime-numbers-with-pipeline)
87 * [Fan-out](#fan-out)
88 * [Fan-in](#fan-in)
89 * [Buffered channels](#buffered-channels)
Roman Elizarovb0517ba2017-02-27 14:03:14 +030090 * [Channels are fair](#channels-are-fair)
Roman Elizarovf5bc0472017-02-22 11:38:13 +030091* [Shared mutable state and concurrency](#shared-mutable-state-and-concurrency)
92 * [The problem](#the-problem)
Roman Elizarov1e459602017-02-27 11:05:17 +030093 * [Volatiles are of no help](#volatiles-are-of-no-help)
Roman Elizarovf5bc0472017-02-22 11:38:13 +030094 * [Thread-safe data structures](#thread-safe-data-structures)
Roman Elizarov1e459602017-02-27 11:05:17 +030095 * [Thread confinement fine-grained](#thread-confinement-fine-grained)
96 * [Thread confinement coarse-grained](#thread-confinement-coarse-grained)
Roman Elizarovf5bc0472017-02-22 11:38:13 +030097 * [Mutual exclusion](#mutual-exclusion)
98 * [Actors](#actors)
Roman Elizarovd4dcbe22017-02-22 09:57:46 +030099* [Select expression](#select-expression)
100 * [Selecting from channels](#selecting-from-channels)
101 * [Selecting on close](#selecting-on-close)
102 * [Selecting to send](#selecting-to-send)
103 * [Selecting deferred values](#selecting-deferred-values)
104 * [Switch over a channel of deferred values](#switch-over-a-channel-of-deferred-values)
Roman Elizarov8db17332017-03-09 12:40:45 +0300105* [Further reading](#further-reading)
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300106
Roman Elizarova5e653f2017-02-13 13:49:55 +0300107<!--- END_TOC -->
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300108
109## Coroutine basics
110
111This section covers basic coroutine concepts.
112
113### Your first coroutine
Roman Elizarov7deefb82017-01-31 10:33:17 +0300114
115Run the following code:
116
117```kotlin
118fun main(args: Array<String>) {
119 launch(CommonPool) { // create new coroutine in common thread pool
120 delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
121 println("World!") // print after delay
122 }
123 println("Hello,") // main function continues while coroutine is delayed
124 Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
125}
126```
127
Roman Elizarove8d79342017-08-29 15:21:21 +0300128> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-01.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300129
130Run this code:
131
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300132```text
Roman Elizarov7deefb82017-01-31 10:33:17 +0300133Hello,
134World!
135```
136
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300137<!--- TEST -->
138
Roman Elizarov419a6c82017-02-09 18:36:22 +0300139Essentially, coroutines are light-weight threads.
140They are launched with [launch] _coroutine builder_.
141You can achieve the same result replacing
Roman Elizarov7deefb82017-01-31 10:33:17 +0300142`launch(CommonPool) { ... }` with `thread { ... }` and `delay(...)` with `Thread.sleep(...)`. Try it.
143
144If you start by replacing `launch(CommonPool)` by `thread`, the compiler produces the following error:
145
146```
147Error: Kotlin: Suspend functions are only allowed to be called from a coroutine or another suspend function
148```
149
Roman Elizarov419a6c82017-02-09 18:36:22 +0300150That is because [delay] is a special _suspending function_ that does not block a thread, but _suspends_
Roman Elizarov7deefb82017-01-31 10:33:17 +0300151coroutine and it can be only used from a coroutine.
152
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300153### Bridging blocking and non-blocking worlds
Roman Elizarov7deefb82017-01-31 10:33:17 +0300154
155The first example mixes _non-blocking_ `delay(...)` and _blocking_ `Thread.sleep(...)` in the same
156code of `main` function. It is easy to get lost. Let's cleanly separate blocking and non-blocking
Roman Elizarov419a6c82017-02-09 18:36:22 +0300157worlds by using [runBlocking]:
Roman Elizarov7deefb82017-01-31 10:33:17 +0300158
159```kotlin
160fun main(args: Array<String>) = runBlocking<Unit> { // start main coroutine
161 launch(CommonPool) { // create new coroutine in common thread pool
162 delay(1000L)
163 println("World!")
164 }
165 println("Hello,") // main coroutine continues while child is delayed
166 delay(2000L) // non-blocking delay for 2 seconds to keep JVM alive
167}
168```
169
Roman Elizarove8d79342017-08-29 15:21:21 +0300170> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-02.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300171
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300172<!--- TEST
173Hello,
174World!
175-->
176
Roman Elizarov419a6c82017-02-09 18:36:22 +0300177The result is the same, but this code uses only non-blocking [delay].
Roman Elizarov7deefb82017-01-31 10:33:17 +0300178
179`runBlocking { ... }` works as an adaptor that is used here to start the top-level main coroutine.
180The regular code outside of `runBlocking` _blocks_, until the coroutine inside `runBlocking` is active.
181
182This is also a way to write unit-tests for suspending functions:
183
184```kotlin
185class MyTest {
186 @Test
187 fun testMySuspendingFunction() = runBlocking<Unit> {
188 // here we can use suspending functions using any assertion style that we like
189 }
190}
191```
Roman Elizarovb3d55a52017-02-03 12:47:21 +0300192
193<!--- CLEAR -->
Roman Elizarov7deefb82017-01-31 10:33:17 +0300194
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300195### Waiting for a job
Roman Elizarov7deefb82017-01-31 10:33:17 +0300196
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300197Delaying for a time while another coroutine is working is not a good approach. Let's explicitly
Roman Elizarov419a6c82017-02-09 18:36:22 +0300198wait (in a non-blocking way) until the background [Job] that we have launched is complete:
Roman Elizarov7deefb82017-01-31 10:33:17 +0300199
200```kotlin
201fun main(args: Array<String>) = runBlocking<Unit> {
202 val job = launch(CommonPool) { // create new coroutine and keep a reference to its Job
203 delay(1000L)
204 println("World!")
205 }
206 println("Hello,")
207 job.join() // wait until child coroutine completes
208}
209```
210
Roman Elizarove8d79342017-08-29 15:21:21 +0300211> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-03.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300212
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300213<!--- TEST
214Hello,
215World!
216-->
217
Roman Elizarov7deefb82017-01-31 10:33:17 +0300218Now the result is still the same, but the code of the main coroutine is not tied to the duration of
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300219the background job in any way. Much better.
Roman Elizarov7deefb82017-01-31 10:33:17 +0300220
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300221### Extract function refactoring
Roman Elizarov7deefb82017-01-31 10:33:17 +0300222
Kafji48fd6282017-05-28 08:25:10 +0700223Let's extract the block of code inside `launch(CommonPool) { ... }` into a separate function. When you
Roman Elizarov7deefb82017-01-31 10:33:17 +0300224perform "Extract function" refactoring on this code you get a new function with `suspend` modifier.
225That is your first _suspending function_. Suspending functions can be used inside coroutines
226just like regular functions, but their additional feature is that they can, in turn,
227use other suspending functions, like `delay` in this example, to _suspend_ execution of a coroutine.
228
229```kotlin
230fun main(args: Array<String>) = runBlocking<Unit> {
231 val job = launch(CommonPool) { doWorld() }
232 println("Hello,")
233 job.join()
234}
235
236// this is your first suspending function
237suspend fun doWorld() {
238 delay(1000L)
239 println("World!")
240}
241```
242
Roman Elizarove8d79342017-08-29 15:21:21 +0300243> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-04.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300244
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300245<!--- TEST
246Hello,
247World!
248-->
249
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300250### Coroutines ARE light-weight
Roman Elizarov7deefb82017-01-31 10:33:17 +0300251
252Run the following code:
253
254```kotlin
255fun main(args: Array<String>) = runBlocking<Unit> {
256 val jobs = List(100_000) { // create a lot of coroutines and list their jobs
257 launch(CommonPool) {
258 delay(1000L)
259 print(".")
260 }
261 }
262 jobs.forEach { it.join() } // wait for all jobs to complete
263}
264```
265
Roman Elizarove8d79342017-08-29 15:21:21 +0300266> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-05.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300267
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300268<!--- TEST lines.size == 1 && lines[0] == ".".repeat(100_000) -->
269
Roman Elizarov7deefb82017-01-31 10:33:17 +0300270It starts 100K coroutines and, after a second, each coroutine prints a dot.
271Now, try that with threads. What would happen? (Most likely your code will produce some sort of out-of-memory error)
272
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300273### Coroutines are like daemon threads
Roman Elizarov7deefb82017-01-31 10:33:17 +0300274
275The following code launches a long-running coroutine that prints "I'm sleeping" twice a second and then
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300276returns from the main function after some delay:
Roman Elizarov7deefb82017-01-31 10:33:17 +0300277
278```kotlin
279fun main(args: Array<String>) = runBlocking<Unit> {
280 launch(CommonPool) {
281 repeat(1000) { i ->
282 println("I'm sleeping $i ...")
283 delay(500L)
284 }
285 }
286 delay(1300L) // just quit after delay
287}
288```
289
Roman Elizarove8d79342017-08-29 15:21:21 +0300290> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-06.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300291
292You can run and see that it prints three lines and terminates:
293
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300294```text
Roman Elizarov7deefb82017-01-31 10:33:17 +0300295I'm sleeping 0 ...
296I'm sleeping 1 ...
297I'm sleeping 2 ...
298```
299
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300300<!--- TEST -->
301
Roman Elizarov7deefb82017-01-31 10:33:17 +0300302Active coroutines do not keep the process alive. They are like daemon threads.
303
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300304## Cancellation and timeouts
305
306This section covers coroutine cancellation and timeouts.
307
308### Cancelling coroutine execution
Roman Elizarov7deefb82017-01-31 10:33:17 +0300309
310In small application the return from "main" method might sound like a good idea to get all coroutines
311implicitly terminated. In a larger, long-running application, you need finer-grained control.
Roman Elizarov419a6c82017-02-09 18:36:22 +0300312The [launch] function returns a [Job] that can be used to cancel running coroutine:
Roman Elizarov7deefb82017-01-31 10:33:17 +0300313
314```kotlin
315fun main(args: Array<String>) = runBlocking<Unit> {
316 val job = launch(CommonPool) {
317 repeat(1000) { i ->
318 println("I'm sleeping $i ...")
319 delay(500L)
320 }
321 }
322 delay(1300L) // delay a bit
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300323 println("main: I'm tired of waiting!")
Roman Elizarov7deefb82017-01-31 10:33:17 +0300324 job.cancel() // cancels the job
325 delay(1300L) // delay a bit to ensure it was cancelled indeed
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300326 println("main: Now I can quit.")
Roman Elizarov7deefb82017-01-31 10:33:17 +0300327}
328```
329
Roman Elizarove8d79342017-08-29 15:21:21 +0300330> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-01.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300331
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300332It produces the following output:
333
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300334```text
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300335I'm sleeping 0 ...
336I'm sleeping 1 ...
337I'm sleeping 2 ...
338main: I'm tired of waiting!
339main: Now I can quit.
340```
341
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300342<!--- TEST -->
343
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300344As soon as main invokes `job.cancel`, we don't see any output from the other coroutine because it was cancelled.
345
346### Cancellation is cooperative
Roman Elizarov7deefb82017-01-31 10:33:17 +0300347
Tair Rzayevaf734622017-02-01 22:30:16 +0200348Coroutine cancellation is _cooperative_. A coroutine code has to cooperate to be cancellable.
Roman Elizarov7deefb82017-01-31 10:33:17 +0300349All the suspending functions in `kotlinx.coroutines` are _cancellable_. They check for cancellation of
Roman Elizarov419a6c82017-02-09 18:36:22 +0300350coroutine and throw [CancellationException] when cancelled. However, if a coroutine is working in
Roman Elizarov7deefb82017-01-31 10:33:17 +0300351a computation and does not check for cancellation, then it cannot be cancelled, like the following
352example shows:
353
354```kotlin
355fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov24cd6542017-08-03 21:20:04 -0700356 val startTime = System.currentTimeMillis()
Roman Elizarov7deefb82017-01-31 10:33:17 +0300357 val job = launch(CommonPool) {
Roman Elizarov24cd6542017-08-03 21:20:04 -0700358 var nextPrintTime = startTime
Roman Elizarov7deefb82017-01-31 10:33:17 +0300359 var i = 0
Roman Elizarov24cd6542017-08-03 21:20:04 -0700360 while (i < 10) { // computation loop, just wastes CPU
361 // print a message twice a second
362 if (System.currentTimeMillis() >= nextPrintTime) {
Roman Elizarov7deefb82017-01-31 10:33:17 +0300363 println("I'm sleeping ${i++} ...")
Roman Elizarov35d2c342017-07-20 14:54:39 +0300364 nextPrintTime += 500L
Roman Elizarov7deefb82017-01-31 10:33:17 +0300365 }
366 }
367 }
368 delay(1300L) // delay a bit
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300369 println("main: I'm tired of waiting!")
Roman Elizarov7deefb82017-01-31 10:33:17 +0300370 job.cancel() // cancels the job
371 delay(1300L) // delay a bit to see if it was cancelled....
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300372 println("main: Now I can quit.")
Roman Elizarov7deefb82017-01-31 10:33:17 +0300373}
374```
375
Roman Elizarove8d79342017-08-29 15:21:21 +0300376> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-02.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300377
378Run it to see that it continues to print "I'm sleeping" even after cancellation.
379
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300380<!--- TEST
381I'm sleeping 0 ...
382I'm sleeping 1 ...
383I'm sleeping 2 ...
384main: I'm tired of waiting!
385I'm sleeping 3 ...
386I'm sleeping 4 ...
387I'm sleeping 5 ...
388main: Now I can quit.
389-->
390
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300391### Making computation code cancellable
Roman Elizarov7deefb82017-01-31 10:33:17 +0300392
393There are two approaches to making computation code cancellable. The first one is to periodically
Roman Elizarov419a6c82017-02-09 18:36:22 +0300394invoke a suspending function. There is a [yield] function that is a good choice for that purpose.
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300395The other one is to explicitly check the cancellation status. Let us try the later approach.
Roman Elizarov7deefb82017-01-31 10:33:17 +0300396
Roman Elizarov24cd6542017-08-03 21:20:04 -0700397Replace `while (i < 10)` in the previous example with `while (isActive)` and rerun it.
Roman Elizarov7deefb82017-01-31 10:33:17 +0300398
Roman Elizarovb3d55a52017-02-03 12:47:21 +0300399```kotlin
400fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov24cd6542017-08-03 21:20:04 -0700401 val startTime = System.currentTimeMillis()
Roman Elizarovb3d55a52017-02-03 12:47:21 +0300402 val job = launch(CommonPool) {
Roman Elizarov24cd6542017-08-03 21:20:04 -0700403 var nextPrintTime = startTime
Roman Elizarovb3d55a52017-02-03 12:47:21 +0300404 var i = 0
405 while (isActive) { // cancellable computation loop
Roman Elizarov24cd6542017-08-03 21:20:04 -0700406 // print a message twice a second
407 if (System.currentTimeMillis() >= nextPrintTime) {
Roman Elizarovb3d55a52017-02-03 12:47:21 +0300408 println("I'm sleeping ${i++} ...")
Roman Elizarov24cd6542017-08-03 21:20:04 -0700409 nextPrintTime += 500L
Roman Elizarovb3d55a52017-02-03 12:47:21 +0300410 }
411 }
412 }
413 delay(1300L) // delay a bit
414 println("main: I'm tired of waiting!")
415 job.cancel() // cancels the job
416 delay(1300L) // delay a bit to see if it was cancelled....
417 println("main: Now I can quit.")
418}
419```
420
Roman Elizarove8d79342017-08-29 15:21:21 +0300421> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-03.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300422
Roman Elizarov419a6c82017-02-09 18:36:22 +0300423As you can see, now this loop can be cancelled. [isActive][CoroutineScope.isActive] is a property that is available inside
424the code of coroutines via [CoroutineScope] object.
Roman Elizarov7deefb82017-01-31 10:33:17 +0300425
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300426<!--- TEST
427I'm sleeping 0 ...
428I'm sleeping 1 ...
429I'm sleeping 2 ...
430main: I'm tired of waiting!
431main: Now I can quit.
432-->
433
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300434### Closing resources with finally
435
Roman Elizarov419a6c82017-02-09 18:36:22 +0300436Cancellable suspending functions throw [CancellationException] on cancellation which can be handled in
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300437all the usual way. For example, the `try {...} finally {...}` and Kotlin `use` function execute their
438finalization actions normally when coroutine is cancelled:
439
440```kotlin
441fun main(args: Array<String>) = runBlocking<Unit> {
442 val job = launch(CommonPool) {
443 try {
444 repeat(1000) { i ->
445 println("I'm sleeping $i ...")
446 delay(500L)
447 }
448 } finally {
449 println("I'm running finally")
450 }
451 }
452 delay(1300L) // delay a bit
453 println("main: I'm tired of waiting!")
454 job.cancel() // cancels the job
455 delay(1300L) // delay a bit to ensure it was cancelled indeed
456 println("main: Now I can quit.")
457}
458```
459
Roman Elizarove8d79342017-08-29 15:21:21 +0300460> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-04.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300461
462The example above produces the following output:
463
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300464```text
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300465I'm sleeping 0 ...
466I'm sleeping 1 ...
467I'm sleeping 2 ...
468main: I'm tired of waiting!
469I'm running finally
470main: Now I can quit.
471```
472
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300473<!--- TEST -->
474
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300475### Run non-cancellable block
476
477Any attempt to use a suspending function in the `finally` block of the previous example will cause
Roman Elizarov419a6c82017-02-09 18:36:22 +0300478[CancellationException], because the coroutine running this code is cancelled. Usually, this is not a
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300479problem, since all well-behaving closing operations (closing a file, cancelling a job, or closing any kind of a
480communication channel) are usually non-blocking and do not involve any suspending functions. However, in the
481rare case when you need to suspend in the cancelled coroutine you can wrap the corresponding code in
Roman Elizarov419a6c82017-02-09 18:36:22 +0300482`run(NonCancellable) {...}` using [run] function and [NonCancellable] context as the following example shows:
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300483
484```kotlin
485fun main(args: Array<String>) = runBlocking<Unit> {
486 val job = launch(CommonPool) {
487 try {
488 repeat(1000) { i ->
489 println("I'm sleeping $i ...")
490 delay(500L)
491 }
492 } finally {
493 run(NonCancellable) {
494 println("I'm running finally")
495 delay(1000L)
496 println("And I've just delayed for 1 sec because I'm non-cancellable")
497 }
498 }
499 }
500 delay(1300L) // delay a bit
501 println("main: I'm tired of waiting!")
502 job.cancel() // cancels the job
503 delay(1300L) // delay a bit to ensure it was cancelled indeed
504 println("main: Now I can quit.")
505}
506```
507
Roman Elizarove8d79342017-08-29 15:21:21 +0300508> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-05.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300509
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300510<!--- TEST
511I'm sleeping 0 ...
512I'm sleeping 1 ...
513I'm sleeping 2 ...
514main: I'm tired of waiting!
515I'm running finally
516And I've just delayed for 1 sec because I'm non-cancellable
517main: Now I can quit.
518-->
519
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300520### Timeout
521
522The most obvious reason to cancel coroutine execution in practice,
523is because its execution time has exceeded some timeout.
Roman Elizarov419a6c82017-02-09 18:36:22 +0300524While you can manually track the reference to the corresponding [Job] and launch a separate coroutine to cancel
525the tracked one after delay, there is a ready to use [withTimeout] function that does it.
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300526Look at the following example:
527
528```kotlin
529fun main(args: Array<String>) = runBlocking<Unit> {
530 withTimeout(1300L) {
531 repeat(1000) { i ->
532 println("I'm sleeping $i ...")
533 delay(500L)
534 }
535 }
536}
537```
538
Roman Elizarove8d79342017-08-29 15:21:21 +0300539> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-06.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300540
541It produces the following output:
542
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300543```text
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300544I'm sleeping 0 ...
545I'm sleeping 1 ...
546I'm sleeping 2 ...
Roman Elizarov63f6ea22017-09-06 18:42:34 +0300547Exception in thread "main" kotlinx.coroutines.experimental.TimeoutCancellationException: Timed out waiting for 1300 MILLISECONDS
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300548```
549
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300550<!--- TEST STARTS_WITH -->
551
Roman Elizarov63f6ea22017-09-06 18:42:34 +0300552The `TimeoutCancellationException` that is thrown by [withTimeout] is a subclass of [CancellationException].
Roman Elizarovca9d5be2017-04-20 19:23:18 +0300553We have not seen its stack trace printed on the console before. That is because
Roman Elizarov7c864d82017-02-27 10:17:50 +0300554inside a cancelled coroutine `CancellationException` is considered to be a normal reason for coroutine completion.
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300555However, in this example we have used `withTimeout` right inside the `main` function.
556
557Because cancellation is just an exception, all the resources will be closed in a usual way.
Roman Elizarov63f6ea22017-09-06 18:42:34 +0300558You can wrap the code with timeout in `try {...} catch (e: TimeoutCancellationException) {...}` block if
559you need to do some additional action specifically on any kind of timeout or use [withTimeoutOrNull] function
560that is similar to [withTimeout], but returns `null` on timeout instead of throwing an exception.
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300561
562## Composing suspending functions
563
564This section covers various approaches to composition of suspending functions.
565
566### Sequential by default
567
568Assume that we have two suspending functions defined elsewhere that do something useful like some kind of
Roman Elizarovb7721cf2017-02-03 19:23:08 +0300569remote service call or computation. We just pretend they are useful, but actually each one just
570delays for a second for the purpose of this example:
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300571
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300572<!--- INCLUDE .*/example-compose-([0-9]+).kt
573import kotlin.system.measureTimeMillis
574-->
575
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300576```kotlin
577suspend fun doSomethingUsefulOne(): Int {
578 delay(1000L) // pretend we are doing something useful here
579 return 13
580}
581
582suspend fun doSomethingUsefulTwo(): Int {
583 delay(1000L) // pretend we are doing something useful here, too
584 return 29
585}
586```
587
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300588<!--- INCLUDE .*/example-compose-([0-9]+).kt -->
589
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300590What do we do if need to invoke them _sequentially_ -- first `doSomethingUsefulOne` _and then_
591`doSomethingUsefulTwo` and compute the sum of their results?
592In practise we do this if we use the results of the first function to make a decision on whether we need
593to invoke the second one or to decide on how to invoke it.
594
595We just use a normal sequential invocation, because the code in the coroutine, just like in the regular
Roman Elizarov32d95322017-02-09 15:57:31 +0300596code, is _sequential_ by default. The following example demonstrates it by measuring the total
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300597time it takes to execute both suspending functions:
598
599```kotlin
600fun main(args: Array<String>) = runBlocking<Unit> {
601 val time = measureTimeMillis {
602 val one = doSomethingUsefulOne()
603 val two = doSomethingUsefulTwo()
604 println("The answer is ${one + two}")
605 }
606 println("Completed in $time ms")
607}
608```
609
Roman Elizarove8d79342017-08-29 15:21:21 +0300610> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-01.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300611
612It produces something like this:
613
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300614```text
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300615The answer is 42
616Completed in 2017 ms
617```
618
Roman Elizarov35d2c342017-07-20 14:54:39 +0300619<!--- TEST ARBITRARY_TIME -->
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300620
Roman Elizarov32d95322017-02-09 15:57:31 +0300621### Concurrent using async
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300622
623What if there are no dependencies between invocation of `doSomethingUsefulOne` and `doSomethingUsefulTwo` and
Roman Elizarov419a6c82017-02-09 18:36:22 +0300624we want to get the answer faster, by doing both _concurrently_? This is where [async] comes to help.
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300625
Roman Elizarov419a6c82017-02-09 18:36:22 +0300626Conceptually, [async] is just like [launch]. It starts a separate coroutine which is a light-weight thread
627that works concurrently with all the other coroutines. The difference is that `launch` returns a [Job] and
628does not carry any resulting value, while `async` returns a [Deferred] -- a light-weight non-blocking future
Roman Elizarov32d95322017-02-09 15:57:31 +0300629that represents a promise to provide a result later. You can use `.await()` on a deferred value to get its eventual result,
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300630but `Deferred` is also a `Job`, so you can cancel it if needed.
631
632```kotlin
633fun main(args: Array<String>) = runBlocking<Unit> {
634 val time = measureTimeMillis {
Roman Elizarov32d95322017-02-09 15:57:31 +0300635 val one = async(CommonPool) { doSomethingUsefulOne() }
636 val two = async(CommonPool) { doSomethingUsefulTwo() }
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300637 println("The answer is ${one.await() + two.await()}")
638 }
639 println("Completed in $time ms")
640}
641```
642
Roman Elizarove8d79342017-08-29 15:21:21 +0300643> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-02.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300644
645It produces something like this:
646
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300647```text
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300648The answer is 42
649Completed in 1017 ms
650```
651
Roman Elizarov35d2c342017-07-20 14:54:39 +0300652<!--- TEST ARBITRARY_TIME -->
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300653
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300654This is twice as fast, because we have concurrent execution of two coroutines.
655Note, that concurrency with coroutines is always explicit.
656
Roman Elizarov32d95322017-02-09 15:57:31 +0300657### Lazily started async
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300658
Roman Elizarovecda27f2017-04-06 23:06:26 +0300659There is a laziness option to [async] with [CoroutineStart.LAZY] parameter.
Roman Elizarov419a6c82017-02-09 18:36:22 +0300660It starts coroutine only when its result is needed by some
661[await][Deferred.await] or if a [start][Job.start] function
Roman Elizarov32d95322017-02-09 15:57:31 +0300662is invoked. Run the following example that differs from the previous one only by this option:
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300663
664```kotlin
665fun main(args: Array<String>) = runBlocking<Unit> {
666 val time = measureTimeMillis {
Roman Elizarovecda27f2017-04-06 23:06:26 +0300667 val one = async(CommonPool, CoroutineStart.LAZY) { doSomethingUsefulOne() }
668 val two = async(CommonPool, CoroutineStart.LAZY) { doSomethingUsefulTwo() }
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300669 println("The answer is ${one.await() + two.await()}")
670 }
671 println("Completed in $time ms")
672}
673```
674
Roman Elizarove8d79342017-08-29 15:21:21 +0300675> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-03.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300676
677It produces something like this:
678
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300679```text
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300680The answer is 42
681Completed in 2017 ms
682```
683
Roman Elizarov35d2c342017-07-20 14:54:39 +0300684<!--- TEST ARBITRARY_TIME -->
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300685
Roman Elizarov32d95322017-02-09 15:57:31 +0300686So, we are back to sequential execution, because we _first_ start and await for `one`, _and then_ start and await
687for `two`. It is not the intended use-case for laziness. It is designed as a replacement for
688the standard `lazy` function in cases when computation of the value involves suspending functions.
689
690### Async-style functions
691
692We can define async-style functions that invoke `doSomethingUsefulOne` and `doSomethingUsefulTwo`
Roman Elizarov419a6c82017-02-09 18:36:22 +0300693_asynchronously_ using [async] coroutine builder. It is a good style to name such functions with
Roman Elizarov32d95322017-02-09 15:57:31 +0300694either "async" prefix of "Async" suffix to highlight the fact that they only start asynchronous
695computation and one needs to use the resulting deferred value to get the result.
696
697```kotlin
698// The result type of asyncSomethingUsefulOne is Deferred<Int>
699fun asyncSomethingUsefulOne() = async(CommonPool) {
700 doSomethingUsefulOne()
701}
702
703// The result type of asyncSomethingUsefulTwo is Deferred<Int>
704fun asyncSomethingUsefulTwo() = async(CommonPool) {
705 doSomethingUsefulTwo()
706}
707```
708
709Note, that these `asyncXXX` function are **not** _suspending_ functions. They can be used from anywhere.
710However, their use always implies asynchronous (here meaning _concurrent_) execution of their action
711with the invoking code.
712
713The following example shows their use outside of coroutine:
714
715```kotlin
716// note, that we don't have `runBlocking` to the right of `main` in this example
717fun main(args: Array<String>) {
718 val time = measureTimeMillis {
719 // we can initiate async actions outside of a coroutine
720 val one = asyncSomethingUsefulOne()
721 val two = asyncSomethingUsefulTwo()
722 // but waiting for a result must involve either suspending or blocking.
723 // here we use `runBlocking { ... }` to block the main thread while waiting for the result
724 runBlocking {
725 println("The answer is ${one.await() + two.await()}")
726 }
727 }
728 println("Completed in $time ms")
729}
730```
731
Roman Elizarove8d79342017-08-29 15:21:21 +0300732> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-04.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300733
Roman Elizarov35d2c342017-07-20 14:54:39 +0300734<!--- TEST ARBITRARY_TIME
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300735The answer is 42
736Completed in 1085 ms
737-->
738
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300739## Coroutine context and dispatchers
740
Roman Elizarov32d95322017-02-09 15:57:31 +0300741We've already seen `launch(CommonPool) {...}`, `async(CommonPool) {...}`, `run(NonCancellable) {...}`, etc.
Roman Elizarov419a6c82017-02-09 18:36:22 +0300742In these code snippets [CommonPool] and [NonCancellable] are _coroutine contexts_.
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300743This section covers other available choices.
744
745### Dispatchers and threads
746
Roman Elizarov419a6c82017-02-09 18:36:22 +0300747Coroutine context includes a [_coroutine dispatcher_][CoroutineDispatcher] which determines what thread or threads
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300748the corresponding coroutine uses for its execution. Coroutine dispatcher can confine coroutine execution
749to a specific thread, dispatch it to a thread pool, or let it run unconfined. Try the following example:
750
751```kotlin
752fun main(args: Array<String>) = runBlocking<Unit> {
753 val jobs = arrayListOf<Job>()
754 jobs += launch(Unconfined) { // not confined -- will work with main thread
Roman Elizarov43e3af72017-07-21 16:01:31 +0300755 println(" 'Unconfined': I'm working in thread ${Thread.currentThread().name}")
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300756 }
Roman Elizarov43e3af72017-07-21 16:01:31 +0300757 jobs += launch(coroutineContext) { // context of the parent, runBlocking coroutine
758 println("'coroutineContext': I'm working in thread ${Thread.currentThread().name}")
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300759 }
760 jobs += launch(CommonPool) { // will get dispatched to ForkJoinPool.commonPool (or equivalent)
Roman Elizarov43e3af72017-07-21 16:01:31 +0300761 println(" 'CommonPool': I'm working in thread ${Thread.currentThread().name}")
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300762 }
763 jobs += launch(newSingleThreadContext("MyOwnThread")) { // will get its own new thread
Roman Elizarov43e3af72017-07-21 16:01:31 +0300764 println(" 'newSTC': I'm working in thread ${Thread.currentThread().name}")
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300765 }
766 jobs.forEach { it.join() }
767}
768```
769
Roman Elizarove8d79342017-08-29 15:21:21 +0300770> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-context-01.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300771
772It produces the following output (maybe in different order):
773
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300774```text
Roman Elizarov43e3af72017-07-21 16:01:31 +0300775 'Unconfined': I'm working in thread main
776 'CommonPool': I'm working in thread ForkJoinPool.commonPool-worker-1
777 'newSTC': I'm working in thread MyOwnThread
778'coroutineContext': I'm working in thread main
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300779```
780
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300781<!--- TEST LINES_START_UNORDERED -->
782
Roman Elizarov43e3af72017-07-21 16:01:31 +0300783The difference between parent [coroutineContext][CoroutineScope.coroutineContext] and
784[Unconfined] context will be shown later.
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300785
786### Unconfined vs confined dispatcher
787
Roman Elizarov419a6c82017-02-09 18:36:22 +0300788The [Unconfined] coroutine dispatcher starts coroutine in the caller thread, but only until the
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300789first suspension point. After suspension it resumes in the thread that is fully determined by the
790suspending function that was invoked. Unconfined dispatcher is appropriate when coroutine does not
791consume CPU time nor updates any shared data (like UI) that is confined to a specific thread.
792
Roman Elizarov43e3af72017-07-21 16:01:31 +0300793On the other side, [coroutineContext][CoroutineScope.coroutineContext] property that is available inside the block of any coroutine
Roman Elizarov419a6c82017-02-09 18:36:22 +0300794via [CoroutineScope] interface, is a reference to a context of this particular coroutine.
795This way, a parent context can be inherited. The default context of [runBlocking], in particular,
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300796is confined to be invoker thread, so inheriting it has the effect of confining execution to
797this thread with a predictable FIFO scheduling.
798
799```kotlin
800fun main(args: Array<String>) = runBlocking<Unit> {
801 val jobs = arrayListOf<Job>()
802 jobs += launch(Unconfined) { // not confined -- will work with main thread
Roman Elizarov43e3af72017-07-21 16:01:31 +0300803 println(" 'Unconfined': I'm working in thread ${Thread.currentThread().name}")
Roman Elizarovd0021622017-03-10 15:43:38 +0300804 delay(500)
Roman Elizarov43e3af72017-07-21 16:01:31 +0300805 println(" 'Unconfined': After delay in thread ${Thread.currentThread().name}")
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300806 }
Roman Elizarov43e3af72017-07-21 16:01:31 +0300807 jobs += launch(coroutineContext) { // context of the parent, runBlocking coroutine
808 println("'coroutineContext': I'm working in thread ${Thread.currentThread().name}")
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300809 delay(1000)
Roman Elizarov43e3af72017-07-21 16:01:31 +0300810 println("'coroutineContext': After delay in thread ${Thread.currentThread().name}")
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300811 }
812 jobs.forEach { it.join() }
813}
814```
815
Roman Elizarove8d79342017-08-29 15:21:21 +0300816> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-context-02.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300817
818Produces the output:
819
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300820```text
Roman Elizarov43e3af72017-07-21 16:01:31 +0300821 'Unconfined': I'm working in thread main
822'coroutineContext': I'm working in thread main
823 'Unconfined': After delay in thread kotlinx.coroutines.DefaultExecutor
824'coroutineContext': After delay in thread main
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300825```
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300826
827<!--- TEST LINES_START -->
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300828
Roman Elizarov43e3af72017-07-21 16:01:31 +0300829So, the coroutine that had inherited `coroutineContext` of `runBlocking {...}` continues to execute
830in the `main` thread, while the unconfined one had resumed in the default executor thread that [delay]
831function is using.
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300832
833### Debugging coroutines and threads
834
Roman Elizarov419a6c82017-02-09 18:36:22 +0300835Coroutines can suspend on one thread and resume on another thread with [Unconfined] dispatcher or
836with a multi-threaded dispatcher like [CommonPool]. Even with a single-threaded dispatcher it might be hard to
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300837figure out what coroutine was doing what, where, and when. The common approach to debugging applications with
838threads is to print the thread name in the log file on each log statement. This feature is universally supported
839by logging frameworks. When using coroutines, the thread name alone does not give much of a context, so
840`kotlinx.coroutines` includes debugging facilities to make it easier.
841
842Run the following code with `-Dkotlinx.coroutines.debug` JVM option:
843
844```kotlin
845fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")
846
847fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov43e3af72017-07-21 16:01:31 +0300848 val a = async(coroutineContext) {
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300849 log("I'm computing a piece of the answer")
850 6
851 }
Roman Elizarov43e3af72017-07-21 16:01:31 +0300852 val b = async(coroutineContext) {
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300853 log("I'm computing another piece of the answer")
854 7
855 }
856 log("The answer is ${a.await() * b.await()}")
857}
858```
859
Roman Elizarove8d79342017-08-29 15:21:21 +0300860> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-context-03.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300861
Roman Elizarovb7721cf2017-02-03 19:23:08 +0300862There are three coroutines. The main coroutine (#1) -- `runBlocking` one,
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300863and two coroutines computing deferred values `a` (#2) and `b` (#3).
864They are all executing in the context of `runBlocking` and are confined to the main thread.
865The output of this code is:
866
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300867```text
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300868[main @coroutine#2] I'm computing a piece of the answer
869[main @coroutine#3] I'm computing another piece of the answer
870[main @coroutine#1] The answer is 42
871```
872
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300873<!--- TEST -->
874
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300875The `log` function prints the name of the thread in square brackets and you can see, that it is the `main`
876thread, but the identifier of the currently executing coroutine is appended to it. This identifier
877is consecutively assigned to all created coroutines when debugging mode is turned on.
878
Roman Elizarov419a6c82017-02-09 18:36:22 +0300879You can read more about debugging facilities in the documentation for [newCoroutineContext] function.
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300880
881### Jumping between threads
882
883Run the following code with `-Dkotlinx.coroutines.debug` JVM option:
884
885```kotlin
886fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")
887
888fun main(args: Array<String>) {
889 val ctx1 = newSingleThreadContext("Ctx1")
890 val ctx2 = newSingleThreadContext("Ctx2")
891 runBlocking(ctx1) {
892 log("Started in ctx1")
893 run(ctx2) {
894 log("Working in ctx2")
895 }
896 log("Back to ctx1")
897 }
898}
899```
900
Roman Elizarove8d79342017-08-29 15:21:21 +0300901> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-context-04.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300902
Roman Elizarov419a6c82017-02-09 18:36:22 +0300903It demonstrates two new techniques. One is using [runBlocking] with an explicitly specified context, and
904the second one is using [run] function to change a context of a coroutine while still staying in the
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300905same coroutine as you can see in the output below:
906
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300907```text
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300908[Ctx1 @coroutine#1] Started in ctx1
909[Ctx2 @coroutine#1] Working in ctx2
910[Ctx1 @coroutine#1] Back to ctx1
911```
912
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300913<!--- TEST -->
914
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300915### Job in the context
916
Roman Elizarov419a6c82017-02-09 18:36:22 +0300917The coroutine [Job] is part of its context. The coroutine can retrieve it from its own context
Roman Elizarov43e3af72017-07-21 16:01:31 +0300918using `coroutineContext[Job]` expression:
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300919
920```kotlin
921fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov43e3af72017-07-21 16:01:31 +0300922 println("My job is ${coroutineContext[Job]}")
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300923}
924```
925
Roman Elizarove8d79342017-08-29 15:21:21 +0300926> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-context-05.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300927
shifujun81a6f232017-06-18 15:37:59 +0800928It produces something like
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300929
930```
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300931My job is BlockingCoroutine{Active}@65ae6ba4
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300932```
933
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300934<!--- TEST lines.size == 1 && lines[0].startsWith("My job is BlockingCoroutine{Active}@") -->
935
Roman Elizarov43e3af72017-07-21 16:01:31 +0300936So, [isActive][CoroutineScope.isActive] in [CoroutineScope] is just a convenient shortcut for
937`coroutineContext[Job]!!.isActive`.
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300938
939### Children of a coroutine
940
Roman Elizarov43e3af72017-07-21 16:01:31 +0300941When [coroutineContext][CoroutineScope.coroutineContext] of a coroutine is used to launch another coroutine,
Roman Elizarov419a6c82017-02-09 18:36:22 +0300942the [Job] of the new coroutine becomes
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300943a _child_ of the parent coroutine's job. When the parent coroutine is cancelled, all its children
944are recursively cancelled, too.
945
946```kotlin
947fun main(args: Array<String>) = runBlocking<Unit> {
948 // start a coroutine to process some kind of incoming request
949 val request = launch(CommonPool) {
950 // it spawns two other jobs, one with its separate context
951 val job1 = launch(CommonPool) {
952 println("job1: I have my own context and execute independently!")
953 delay(1000)
954 println("job1: I am not affected by cancellation of the request")
955 }
956 // and the other inherits the parent context
Roman Elizarov43e3af72017-07-21 16:01:31 +0300957 val job2 = launch(coroutineContext) {
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300958 println("job2: I am a child of the request coroutine")
959 delay(1000)
960 println("job2: I will not execute this line if my parent request is cancelled")
961 }
962 // request completes when both its sub-jobs complete:
963 job1.join()
964 job2.join()
965 }
966 delay(500)
967 request.cancel() // cancel processing of the request
968 delay(1000) // delay a second to see what happens
969 println("main: Who has survived request cancellation?")
970}
971```
972
Roman Elizarove8d79342017-08-29 15:21:21 +0300973> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-context-06.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300974
975The output of this code is:
976
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300977```text
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300978job1: I have my own context and execute independently!
979job2: I am a child of the request coroutine
980job1: I am not affected by cancellation of the request
981main: Who has survived request cancellation?
982```
983
Roman Elizarov731f0ad2017-02-22 20:48:45 +0300984<!--- TEST -->
985
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300986### Combining contexts
987
988Coroutine context can be combined using `+` operator. The context on the right-hand side replaces relevant entries
Roman Elizarov419a6c82017-02-09 18:36:22 +0300989of the context on the left-hand side. For example, a [Job] of the parent coroutine can be inherited, while
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300990its dispatcher replaced:
991
992```kotlin
993fun main(args: Array<String>) = runBlocking<Unit> {
994 // start a coroutine to process some kind of incoming request
Roman Elizarov43e3af72017-07-21 16:01:31 +0300995 val request = launch(coroutineContext) { // use the context of `runBlocking`
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300996 // spawns CPU-intensive child job in CommonPool !!!
Roman Elizarov43e3af72017-07-21 16:01:31 +0300997 val job = launch(coroutineContext + CommonPool) {
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300998 println("job: I am a child of the request coroutine, but with a different dispatcher")
999 delay(1000)
1000 println("job: I will not execute this line if my parent request is cancelled")
1001 }
1002 job.join() // request completes when its sub-job completes
1003 }
1004 delay(500)
1005 request.cancel() // cancel processing of the request
1006 delay(1000) // delay a second to see what happens
1007 println("main: Who has survived request cancellation?")
1008}
1009```
1010
Roman Elizarove8d79342017-08-29 15:21:21 +03001011> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-context-07.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +03001012
1013The expected outcome of this code is:
1014
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001015```text
Roman Elizarov2f6d7c92017-02-03 15:16:07 +03001016job: I am a child of the request coroutine, but with a different dispatcher
1017main: Who has survived request cancellation?
1018```
1019
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001020<!--- TEST -->
1021
Roman Elizarov2f6d7c92017-02-03 15:16:07 +03001022### Naming coroutines for debugging
1023
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001024Automatically assigned ids are good when coroutines log often and you just need to correlate log records
Roman Elizarov2f6d7c92017-02-03 15:16:07 +03001025coming from the same coroutine. However, when coroutine is tied to the processing of a specific request
1026or doing some specific background task, it is better to name it explicitly for debugging purposes.
Roman Elizarov419a6c82017-02-09 18:36:22 +03001027[CoroutineName] serves the same function as a thread name. It'll get displayed in the thread name that
Victor Osolovskiyed5ed492017-06-25 00:03:35 +03001028is executing this coroutine when debugging mode is turned on.
Roman Elizarov2f6d7c92017-02-03 15:16:07 +03001029
1030The following example demonstrates this concept:
1031
1032```kotlin
1033fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")
1034
1035fun main(args: Array<String>) = runBlocking(CoroutineName("main")) {
1036 log("Started main coroutine")
1037 // run two background value computations
Roman Elizarov32d95322017-02-09 15:57:31 +03001038 val v1 = async(CommonPool + CoroutineName("v1coroutine")) {
Roman Elizarov2f6d7c92017-02-03 15:16:07 +03001039 log("Computing v1")
1040 delay(500)
1041 252
1042 }
Roman Elizarov32d95322017-02-09 15:57:31 +03001043 val v2 = async(CommonPool + CoroutineName("v2coroutine")) {
Roman Elizarov2f6d7c92017-02-03 15:16:07 +03001044 log("Computing v2")
1045 delay(1000)
1046 6
1047 }
1048 log("The answer for v1 / v2 = ${v1.await() / v2.await()}")
1049}
1050```
1051
Roman Elizarove8d79342017-08-29 15:21:21 +03001052> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-context-08.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +03001053
1054The output it produces with `-Dkotlinx.coroutines.debug` JVM option is similar to:
1055
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001056```text
Roman Elizarov2f6d7c92017-02-03 15:16:07 +03001057[main @main#1] Started main coroutine
1058[ForkJoinPool.commonPool-worker-1 @v1coroutine#2] Computing v1
1059[ForkJoinPool.commonPool-worker-2 @v2coroutine#3] Computing v2
1060[main @main#1] The answer for v1 / v2 = 42
1061```
Roman Elizarov1293ccd2017-02-01 18:49:54 +03001062
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001063<!--- TEST FLEXIBLE_THREAD -->
1064
Roman Elizarov2fd7cb32017-02-11 23:18:59 +03001065### Cancellation via explicit job
1066
1067Let us put our knowledge about contexts, children and jobs together. Assume that our application has
1068an object with a lifecycle, but that object is not a coroutine. For example, we are writing an Android application
1069and launch various coroutines in the context of an Android activity to perform asynchronous operations to fetch
1070and update data, do animations, etc. All of these coroutines must be cancelled when activity is destroyed
1071to avoid memory leaks.
1072
1073We can manage a lifecycle of our coroutines by creating an instance of [Job] that is tied to
Roman Elizarov256812a2017-07-22 01:00:30 +03001074the lifecycle of our activity. A job instance is created using [`Job()`][Job] factory function
Roman Elizarov2fd7cb32017-02-11 23:18:59 +03001075as the following example shows. We need to make sure that all the coroutines are started
1076with this job in their context and then a single invocation of [Job.cancel] terminates them all.
1077
1078```kotlin
1079fun main(args: Array<String>) = runBlocking<Unit> {
1080 val job = Job() // create a job object to manage our lifecycle
1081 // now launch ten coroutines for a demo, each working for a different time
1082 val coroutines = List(10) { i ->
1083 // they are all children of our job object
Roman Elizarov43e3af72017-07-21 16:01:31 +03001084 launch(coroutineContext + job) { // we use the context of main runBlocking thread, but with our own job object
Roman Elizarov2fd7cb32017-02-11 23:18:59 +03001085 delay(i * 200L) // variable delay 0ms, 200ms, 400ms, ... etc
1086 println("Coroutine $i is done")
1087 }
1088 }
1089 println("Launched ${coroutines.size} coroutines")
1090 delay(500L) // delay for half a second
1091 println("Cancelling job!")
1092 job.cancel() // cancel our job.. !!!
1093 delay(1000L) // delay for more to see if our coroutines are still working
1094}
1095```
1096
Roman Elizarove8d79342017-08-29 15:21:21 +03001097> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-context-09.kt)
Roman Elizarov2fd7cb32017-02-11 23:18:59 +03001098
1099The output of this example is:
1100
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001101```text
Roman Elizarov2fd7cb32017-02-11 23:18:59 +03001102Launched 10 coroutines
1103Coroutine 0 is done
1104Coroutine 1 is done
1105Coroutine 2 is done
1106Cancelling job!
1107```
1108
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001109<!--- TEST -->
1110
Roman Elizarov2fd7cb32017-02-11 23:18:59 +03001111As you can see, only the first three coroutines had printed a message and the others were cancelled
1112by a single invocation of `job.cancel()`. So all we need to do in our hypothetical Android
1113application is to create a parent job object when activity is created, use it for child coroutines,
1114and cancel it when activity is destroyed.
1115
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001116## Channels
Roman Elizarov7deefb82017-01-31 10:33:17 +03001117
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001118Deferred values provide a convenient way to transfer a single value between coroutines.
1119Channels provide a way to transfer a stream of values.
1120
1121<!--- INCLUDE .*/example-channel-([0-9]+).kt
1122import kotlinx.coroutines.experimental.channels.*
1123-->
1124
1125### Channel basics
1126
Roman Elizarov419a6c82017-02-09 18:36:22 +03001127A [Channel] is conceptually very similar to `BlockingQueue`. One key difference is that
1128instead of a blocking `put` operation it has a suspending [send][SendChannel.send], and instead of
1129a blocking `take` operation it has a suspending [receive][ReceiveChannel.receive].
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001130
1131```kotlin
1132fun main(args: Array<String>) = runBlocking<Unit> {
1133 val channel = Channel<Int>()
1134 launch(CommonPool) {
1135 // this might be heavy CPU-consuming computation or async logic, we'll just send five squares
1136 for (x in 1..5) channel.send(x * x)
1137 }
1138 // here we print five received integers:
1139 repeat(5) { println(channel.receive()) }
1140 println("Done!")
1141}
1142```
1143
Roman Elizarove8d79342017-08-29 15:21:21 +03001144> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-01.kt)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001145
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001146The output of this code is:
1147
1148```text
11491
11504
11519
115216
115325
1154Done!
1155```
1156
1157<!--- TEST -->
1158
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001159### Closing and iteration over channels
1160
1161Unlike a queue, a channel can be closed to indicate that no more elements are coming.
1162On the receiver side it is convenient to use a regular `for` loop to receive elements
1163from the channel.
1164
Roman Elizarov419a6c82017-02-09 18:36:22 +03001165Conceptually, a [close][SendChannel.close] is like sending a special close token to the channel.
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001166The iteration stops as soon as this close token is received, so there is a guarantee
1167that all previously sent elements before the close are received:
1168
1169```kotlin
1170fun main(args: Array<String>) = runBlocking<Unit> {
1171 val channel = Channel<Int>()
1172 launch(CommonPool) {
1173 for (x in 1..5) channel.send(x * x)
1174 channel.close() // we're done sending
1175 }
1176 // here we print received values using `for` loop (until the channel is closed)
1177 for (y in channel) println(y)
1178 println("Done!")
1179}
1180```
1181
Roman Elizarove8d79342017-08-29 15:21:21 +03001182> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-02.kt)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001183
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001184<!--- TEST
11851
11864
11879
118816
118925
1190Done!
1191-->
1192
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001193### Building channel producers
1194
Roman Elizarova5e653f2017-02-13 13:49:55 +03001195The pattern where a coroutine is producing a sequence of elements is quite common.
1196This is a part of _producer-consumer_ pattern that is often found in concurrent code.
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001197You could abstract such a producer into a function that takes channel as its parameter, but this goes contrary
Roman Elizarova5e653f2017-02-13 13:49:55 +03001198to common sense that results must be returned from functions.
1199
Roman Elizarov86349be2017-03-17 16:47:37 +03001200There is a convenience coroutine builder named [produce] that makes it easy to do it right on producer side,
1201and an extension function [consumeEach], that can replace a `for` loop on the consumer side:
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001202
1203```kotlin
Roman Elizarova5e653f2017-02-13 13:49:55 +03001204fun produceSquares() = produce<Int>(CommonPool) {
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001205 for (x in 1..5) send(x * x)
1206}
1207
1208fun main(args: Array<String>) = runBlocking<Unit> {
1209 val squares = produceSquares()
Roman Elizarov86349be2017-03-17 16:47:37 +03001210 squares.consumeEach { println(it) }
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001211 println("Done!")
1212}
1213```
1214
Roman Elizarove8d79342017-08-29 15:21:21 +03001215> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-03.kt)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001216
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001217<!--- TEST
12181
12194
12209
122116
122225
1223Done!
1224-->
1225
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001226### Pipelines
1227
1228Pipeline is a pattern where one coroutine is producing, possibly infinite, stream of values:
1229
1230```kotlin
Roman Elizarova5e653f2017-02-13 13:49:55 +03001231fun produceNumbers() = produce<Int>(CommonPool) {
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001232 var x = 1
1233 while (true) send(x++) // infinite stream of integers starting from 1
1234}
1235```
1236
Roman Elizarova5e653f2017-02-13 13:49:55 +03001237And another coroutine or coroutines are consuming that stream, doing some processing, and producing some other results.
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001238In the below example the numbers are just squared:
1239
1240```kotlin
Roman Elizarova5e653f2017-02-13 13:49:55 +03001241fun square(numbers: ReceiveChannel<Int>) = produce<Int>(CommonPool) {
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001242 for (x in numbers) send(x * x)
1243}
1244```
1245
Roman Elizarova5e653f2017-02-13 13:49:55 +03001246The main code starts and connects the whole pipeline:
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001247
1248```kotlin
1249fun main(args: Array<String>) = runBlocking<Unit> {
1250 val numbers = produceNumbers() // produces integers from 1 and on
1251 val squares = square(numbers) // squares integers
1252 for (i in 1..5) println(squares.receive()) // print first five
1253 println("Done!") // we are done
1254 squares.cancel() // need to cancel these coroutines in a larger app
1255 numbers.cancel()
1256}
1257```
1258
Roman Elizarove8d79342017-08-29 15:21:21 +03001259> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-04.kt)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001260
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001261<!--- TEST
12621
12634
12649
126516
126625
1267Done!
1268-->
1269
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001270We don't have to cancel these coroutines in this example app, because
1271[coroutines are like daemon threads](#coroutines-are-like-daemon-threads),
1272but in a larger app we'll need to stop our pipeline if we don't need it anymore.
1273Alternatively, we could have run pipeline coroutines as
1274[children of a coroutine](#children-of-a-coroutine).
1275
1276### Prime numbers with pipeline
1277
Cedric Beustfa0b28f2017-02-07 07:07:25 -08001278Let's take pipelines to the extreme with an example that generates prime numbers using a pipeline
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001279of coroutines. We start with an infinite sequence of numbers. This time we introduce an
1280explicit context parameter, so that caller can control where our coroutines run:
1281
Roman Elizarove8d79342017-08-29 15:21:21 +03001282<!--- INCLUDE core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-05.kt
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001283import kotlin.coroutines.experimental.CoroutineContext
1284-->
1285
1286```kotlin
Roman Elizarova5e653f2017-02-13 13:49:55 +03001287fun numbersFrom(context: CoroutineContext, start: Int) = produce<Int>(context) {
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001288 var x = start
1289 while (true) send(x++) // infinite stream of integers from start
1290}
1291```
1292
1293The following pipeline stage filters an incoming stream of numbers, removing all the numbers
1294that are divisible by the given prime number:
1295
1296```kotlin
Roman Elizarova5e653f2017-02-13 13:49:55 +03001297fun filter(context: CoroutineContext, numbers: ReceiveChannel<Int>, prime: Int) = produce<Int>(context) {
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001298 for (x in numbers) if (x % prime != 0) send(x)
1299}
1300```
1301
1302Now we build our pipeline by starting a stream of numbers from 2, taking a prime number from the current channel,
Roman Elizarov62500ba2017-02-09 18:55:40 +03001303and launching new pipeline stage for each prime number found:
1304
1305```
Roman Elizarova5e653f2017-02-13 13:49:55 +03001306numbersFrom(2) -> filter(2) -> filter(3) -> filter(5) -> filter(7) ...
Roman Elizarov62500ba2017-02-09 18:55:40 +03001307```
1308
1309The following example prints the first ten prime numbers,
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001310running the whole pipeline in the context of the main thread:
1311
1312```kotlin
1313fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov43e3af72017-07-21 16:01:31 +03001314 var cur = numbersFrom(coroutineContext, 2)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001315 for (i in 1..10) {
1316 val prime = cur.receive()
1317 println(prime)
Roman Elizarov43e3af72017-07-21 16:01:31 +03001318 cur = filter(coroutineContext, cur, prime)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001319 }
1320}
1321```
1322
Roman Elizarove8d79342017-08-29 15:21:21 +03001323> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-05.kt)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001324
1325The output of this code is:
1326
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001327```text
Roman Elizarovb7721cf2017-02-03 19:23:08 +030013282
13293
13305
13317
133211
133313
133417
133519
133623
133729
1338```
1339
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001340<!--- TEST -->
1341
Roman Elizarova5e653f2017-02-13 13:49:55 +03001342Note, that you can build the same pipeline using `buildIterator` coroutine builder from the standard library.
1343Replace `produce` with `buildIterator`, `send` with `yield`, `receive` with `next`,
Roman Elizarov62500ba2017-02-09 18:55:40 +03001344`ReceiveChannel` with `Iterator`, and get rid of the context. You will not need `runBlocking` either.
1345However, the benefit of a pipeline that uses channels as shown above is that it can actually use
1346multiple CPU cores if you run it in [CommonPool] context.
1347
Roman Elizarova5e653f2017-02-13 13:49:55 +03001348Anyway, this is an extremely impractical way to find prime numbers. In practice, pipelines do involve some
Roman Elizarov62500ba2017-02-09 18:55:40 +03001349other suspending invocations (like asynchronous calls to remote services) and these pipelines cannot be
1350built using `buildSeqeunce`/`buildIterator`, because they do not allow arbitrary suspension, unlike
Roman Elizarova5e653f2017-02-13 13:49:55 +03001351`produce` which is fully asynchronous.
Roman Elizarov62500ba2017-02-09 18:55:40 +03001352
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001353### Fan-out
1354
1355Multiple coroutines may receive from the same channel, distributing work between themselves.
1356Let us start with a producer coroutine that is periodically producing integers
1357(ten numbers per second):
1358
1359```kotlin
Roman Elizarova5e653f2017-02-13 13:49:55 +03001360fun produceNumbers() = produce<Int>(CommonPool) {
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001361 var x = 1 // start from 1
1362 while (true) {
1363 send(x++) // produce next
1364 delay(100) // wait 0.1s
1365 }
1366}
1367```
1368
1369Then we can have several processor coroutines. In this example, they just print their id and
1370received number:
1371
1372```kotlin
1373fun launchProcessor(id: Int, channel: ReceiveChannel<Int>) = launch(CommonPool) {
Roman Elizarov86349be2017-03-17 16:47:37 +03001374 channel.consumeEach {
1375 println("Processor #$id received $it")
Roman Elizarovec9384c2017-03-02 22:09:08 +03001376 }
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001377}
1378```
1379
Roman Elizarov35d2c342017-07-20 14:54:39 +03001380Now let us launch five processors and let them work for almost a second. See what happens:
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001381
1382```kotlin
1383fun main(args: Array<String>) = runBlocking<Unit> {
1384 val producer = produceNumbers()
1385 repeat(5) { launchProcessor(it, producer) }
Roman Elizarov35d2c342017-07-20 14:54:39 +03001386 delay(950)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001387 producer.cancel() // cancel producer coroutine and thus kill them all
1388}
1389```
1390
Roman Elizarove8d79342017-08-29 15:21:21 +03001391> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-06.kt)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001392
1393The output will be similar to the the following one, albeit the processor ids that receive
1394each specific integer may be different:
1395
1396```
1397Processor #2 received 1
1398Processor #4 received 2
1399Processor #0 received 3
1400Processor #1 received 4
1401Processor #3 received 5
1402Processor #2 received 6
1403Processor #4 received 7
1404Processor #0 received 8
1405Processor #1 received 9
1406Processor #3 received 10
1407```
1408
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001409<!--- TEST lines.size == 10 && lines.withIndex().all { (i, line) -> line.startsWith("Processor #") && line.endsWith(" received ${i + 1}") } -->
1410
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001411Note, that cancelling a producer coroutine closes its channel, thus eventually terminating iteration
1412over the channel that processor coroutines are doing.
1413
1414### Fan-in
1415
1416Multiple coroutines may send to the same channel.
1417For example, let us have a channel of strings, and a suspending function that
1418repeatedly sends a specified string to this channel with a specified delay:
1419
1420```kotlin
1421suspend fun sendString(channel: SendChannel<String>, s: String, time: Long) {
1422 while (true) {
1423 delay(time)
1424 channel.send(s)
1425 }
1426}
1427```
1428
Cedric Beustfa0b28f2017-02-07 07:07:25 -08001429Now, let us see what happens if we launch a couple of coroutines sending strings
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001430(in this example we launch them in the context of the main thread):
1431
1432```kotlin
1433fun main(args: Array<String>) = runBlocking<Unit> {
1434 val channel = Channel<String>()
Roman Elizarov43e3af72017-07-21 16:01:31 +03001435 launch(coroutineContext) { sendString(channel, "foo", 200L) }
1436 launch(coroutineContext) { sendString(channel, "BAR!", 500L) }
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001437 repeat(6) { // receive first six
1438 println(channel.receive())
1439 }
1440}
1441```
1442
Roman Elizarove8d79342017-08-29 15:21:21 +03001443> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-07.kt)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001444
1445The output is:
1446
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001447```text
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001448foo
1449foo
1450BAR!
1451foo
1452foo
1453BAR!
1454```
1455
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001456<!--- TEST -->
1457
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001458### Buffered channels
1459
1460The channels shown so far had no buffer. Unbuffered channels transfer elements when sender and receiver
1461meet each other (aka rendezvous). If send is invoked first, then it is suspended until receive is invoked,
1462if receive is invoked first, it is suspended until send is invoked.
Roman Elizarov419a6c82017-02-09 18:36:22 +03001463
Roman Elizarov256812a2017-07-22 01:00:30 +03001464Both [`Channel()`][Channel] factory function and [produce] builder take an optional `capacity` parameter to
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001465specify _buffer size_. Buffer allows senders to send multiple elements before suspending,
1466similar to the `BlockingQueue` with a specified capacity, which blocks when buffer is full.
1467
1468Take a look at the behavior of the following code:
1469
1470```kotlin
1471fun main(args: Array<String>) = runBlocking<Unit> {
1472 val channel = Channel<Int>(4) // create buffered channel
Roman Elizarov43e3af72017-07-21 16:01:31 +03001473 launch(coroutineContext) { // launch sender coroutine
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001474 repeat(10) {
1475 println("Sending $it") // print before sending each element
1476 channel.send(it) // will suspend when buffer is full
1477 }
1478 }
1479 // don't receive anything... just wait....
1480 delay(1000)
1481}
1482```
1483
Roman Elizarove8d79342017-08-29 15:21:21 +03001484> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-08.kt)
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001485
1486It prints "sending" _five_ times using a buffered channel with capacity of _four_:
1487
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001488```text
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001489Sending 0
1490Sending 1
1491Sending 2
1492Sending 3
1493Sending 4
1494```
1495
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001496<!--- TEST -->
1497
Roman Elizarovb7721cf2017-02-03 19:23:08 +03001498The first four elements are added to the buffer and the sender suspends when trying to send the fifth one.
Roman Elizarov419a6c82017-02-09 18:36:22 +03001499
Roman Elizarovb0517ba2017-02-27 14:03:14 +03001500
1501### Channels are fair
1502
1503Send and receive operations to channels are _fair_ with respect to the order of their invocation from
1504multiple coroutines. They are served in first-in first-out order, e.g. the first coroutine to invoke `receive`
1505gets the element. In the following example two coroutines "ping" and "pong" are
1506receiving the "ball" object from the shared "table" channel.
1507
1508```kotlin
1509data class Ball(var hits: Int)
1510
1511fun main(args: Array<String>) = runBlocking<Unit> {
1512 val table = Channel<Ball>() // a shared table
Roman Elizarov43e3af72017-07-21 16:01:31 +03001513 launch(coroutineContext) { player("ping", table) }
1514 launch(coroutineContext) { player("pong", table) }
Roman Elizarovb0517ba2017-02-27 14:03:14 +03001515 table.send(Ball(0)) // serve the ball
1516 delay(1000) // delay 1 second
1517 table.receive() // game over, grab the ball
1518}
1519
1520suspend fun player(name: String, table: Channel<Ball>) {
1521 for (ball in table) { // receive the ball in a loop
1522 ball.hits++
1523 println("$name $ball")
Roman Elizarovf526b132017-03-10 16:07:14 +03001524 delay(300) // wait a bit
Roman Elizarovb0517ba2017-02-27 14:03:14 +03001525 table.send(ball) // send the ball back
1526 }
1527}
1528```
1529
Roman Elizarove8d79342017-08-29 15:21:21 +03001530> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-09.kt)
Roman Elizarovb0517ba2017-02-27 14:03:14 +03001531
1532The "ping" coroutine is started first, so it is the first one to receive the ball. Even though "ping"
1533coroutine immediately starts receiving the ball again after sending it back to the table, the ball gets
1534received by the "pong" coroutine, because it was already waiting for it:
1535
1536```text
1537ping Ball(hits=1)
1538pong Ball(hits=2)
1539ping Ball(hits=3)
1540pong Ball(hits=4)
1541ping Ball(hits=5)
Roman Elizarovb0517ba2017-02-27 14:03:14 +03001542```
1543
1544<!--- TEST -->
1545
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001546## Shared mutable state and concurrency
1547
1548Coroutines can be executed concurrently using a multi-threaded dispatcher like [CommonPool]. It presents
1549all the usual concurrency problems. The main problem being synchronization of access to **shared mutable state**.
1550Some solutions to this problem in the land of coroutines are similar to the solutions in the multi-threaded world,
1551but others are unique.
1552
1553### The problem
1554
Roman Elizarov1e459602017-02-27 11:05:17 +03001555Let us launch a thousand coroutines all doing the same action thousand times (for a total of a million executions).
1556We'll also measure their completion time for further comparisons:
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001557
Roman Elizarov43e90112017-05-10 11:25:20 +03001558<!--- INCLUDE .*/example-sync-([0-9a-z]+).kt
Roman Elizarov1e459602017-02-27 11:05:17 +03001559import kotlin.coroutines.experimental.CoroutineContext
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001560import kotlin.system.measureTimeMillis
1561-->
1562
Roman Elizarov1e459602017-02-27 11:05:17 +03001563<!--- INCLUDE .*/example-sync-03.kt
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001564import java.util.concurrent.atomic.AtomicInteger
1565-->
1566
Roman Elizarov1e459602017-02-27 11:05:17 +03001567<!--- INCLUDE .*/example-sync-06.kt
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001568import kotlinx.coroutines.experimental.sync.Mutex
1569-->
1570
Roman Elizarov1e459602017-02-27 11:05:17 +03001571<!--- INCLUDE .*/example-sync-07.kt
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001572import kotlinx.coroutines.experimental.channels.*
1573-->
1574
1575```kotlin
Roman Elizarov1e459602017-02-27 11:05:17 +03001576suspend fun massiveRun(context: CoroutineContext, action: suspend () -> Unit) {
1577 val n = 1000 // number of coroutines to launch
1578 val k = 1000 // times an action is repeated by each coroutine
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001579 val time = measureTimeMillis {
1580 val jobs = List(n) {
Roman Elizarov1e459602017-02-27 11:05:17 +03001581 launch(context) {
1582 repeat(k) { action() }
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001583 }
1584 }
1585 jobs.forEach { it.join() }
1586 }
Roman Elizarov1e459602017-02-27 11:05:17 +03001587 println("Completed ${n * k} actions in $time ms")
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001588}
1589```
1590
Roman Elizarov43e90112017-05-10 11:25:20 +03001591<!--- INCLUDE .*/example-sync-([0-9a-z]+).kt -->
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001592
Roman Elizarov1e459602017-02-27 11:05:17 +03001593We start with a very simple action that increments a shared mutable variable using
1594multi-threaded [CommonPool] context.
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001595
1596```kotlin
1597var counter = 0
1598
1599fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov1e459602017-02-27 11:05:17 +03001600 massiveRun(CommonPool) {
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001601 counter++
1602 }
1603 println("Counter = $counter")
1604}
1605```
1606
Roman Elizarove8d79342017-08-29 15:21:21 +03001607> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-sync-01.kt)
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001608
Roman Elizarov1e459602017-02-27 11:05:17 +03001609<!--- TEST LINES_START
1610Completed 1000000 actions in
1611Counter =
1612-->
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001613
Roman Elizarov1e459602017-02-27 11:05:17 +03001614What does it print at the end? It is highly unlikely to ever print "Counter = 1000000", because a thousand coroutines
1615increment the `counter` concurrently from multiple threads without any synchronization.
1616
Roman Elizarov43e90112017-05-10 11:25:20 +03001617> Note: if you have an old system with 2 or fewer CPUs, then you _will_ consistently see 1000000, because
1618`CommonPool` is running in only one thread in this case. To reproduce the problem you'll need to make the
1619following change:
1620
1621```kotlin
1622val mtContext = newFixedThreadPoolContext(2, "mtPool") // explicitly define context with two threads
1623var counter = 0
1624
1625fun main(args: Array<String>) = runBlocking<Unit> {
1626 massiveRun(mtContext) { // use it instead of CommonPool in this sample and below
1627 counter++
1628 }
1629 println("Counter = $counter")
1630}
1631```
1632
Roman Elizarove8d79342017-08-29 15:21:21 +03001633> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-sync-01b.kt)
Roman Elizarov43e90112017-05-10 11:25:20 +03001634
1635<!--- TEST LINES_START
1636Completed 1000000 actions in
1637Counter =
1638-->
1639
Roman Elizarov1e459602017-02-27 11:05:17 +03001640### Volatiles are of no help
1641
1642There is common misconception that making a variable `volatile` solves concurrency problem. Let us try it:
1643
1644```kotlin
1645@Volatile // in Kotlin `volatile` is an annotation
1646var counter = 0
1647
1648fun main(args: Array<String>) = runBlocking<Unit> {
1649 massiveRun(CommonPool) {
1650 counter++
1651 }
1652 println("Counter = $counter")
1653}
1654```
1655
Roman Elizarove8d79342017-08-29 15:21:21 +03001656> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-sync-02.kt)
Roman Elizarov1e459602017-02-27 11:05:17 +03001657
1658<!--- TEST LINES_START
1659Completed 1000000 actions in
1660Counter =
1661-->
1662
1663This code works slower, but we still don't get "Counter = 1000000" at the end, because volatile variables guarantee
1664linearizable (this is a technical term for "atomic") reads and writes to the corresponding variable, but
1665do not provide atomicity of larger actions (increment in our case).
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001666
1667### Thread-safe data structures
1668
1669The general solution that works both for threads and for coroutines is to use a thread-safe (aka synchronized,
1670linearizable, or atomic) data structure that provides all the necessarily synchronization for the corresponding
1671operations that needs to be performed on a shared state.
Roman Elizarov1e459602017-02-27 11:05:17 +03001672In the case of a simple counter we can use `AtomicInteger` class which has atomic `incrementAndGet` operations:
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001673
1674```kotlin
1675var counter = AtomicInteger()
1676
1677fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov1e459602017-02-27 11:05:17 +03001678 massiveRun(CommonPool) {
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001679 counter.incrementAndGet()
1680 }
1681 println("Counter = ${counter.get()}")
1682}
1683```
1684
Roman Elizarove8d79342017-08-29 15:21:21 +03001685> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-sync-03.kt)
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001686
Roman Elizarov1e459602017-02-27 11:05:17 +03001687<!--- TEST ARBITRARY_TIME
1688Completed 1000000 actions in xxx ms
1689Counter = 1000000
1690-->
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001691
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001692This is the fastest solution for this particular problem. It works for plain counters, collections, queues and other
1693standard data structures and basic operations on them. However, it does not easily scale to complex
1694state or to complex operations that do not have ready-to-use thread-safe implementations.
1695
Roman Elizarov1e459602017-02-27 11:05:17 +03001696### Thread confinement fine-grained
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001697
Roman Elizarov1e459602017-02-27 11:05:17 +03001698_Thread confinement_ is an approach to the problem of shared mutable state where all access to the particular shared
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001699state is confined to a single thread. It is typically used in UI applications, where all UI state is confined to
1700the single event-dispatch/application thread. It is easy to apply with coroutines by using a
1701single-threaded context:
1702
1703```kotlin
1704val counterContext = newSingleThreadContext("CounterContext")
1705var counter = 0
1706
1707fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov1e459602017-02-27 11:05:17 +03001708 massiveRun(CommonPool) { // run each coroutine in CommonPool
1709 run(counterContext) { // but confine each increment to the single-threaded context
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001710 counter++
1711 }
1712 }
1713 println("Counter = $counter")
1714}
1715```
1716
Roman Elizarove8d79342017-08-29 15:21:21 +03001717> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-sync-04.kt)
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001718
Roman Elizarov1e459602017-02-27 11:05:17 +03001719<!--- TEST ARBITRARY_TIME
1720Completed 1000000 actions in xxx ms
1721Counter = 1000000
1722-->
1723
1724This code works very slowly, because it does _fine-grained_ thread-confinement. Each individual increment switches
1725from multi-threaded `CommonPool` context to the single-threaded context using [run] block.
1726
1727### Thread confinement coarse-grained
1728
1729In practice, thread confinement is performed in large chunks, e.g. big pieces of state-updating business logic
1730are confined to the single thread. The following example does it like that, running each coroutine in
1731the single-threaded context to start with.
1732
1733```kotlin
1734val counterContext = newSingleThreadContext("CounterContext")
1735var counter = 0
1736
1737fun main(args: Array<String>) = runBlocking<Unit> {
1738 massiveRun(counterContext) { // run each coroutine in the single-threaded context
1739 counter++
1740 }
1741 println("Counter = $counter")
1742}
1743```
1744
Roman Elizarove8d79342017-08-29 15:21:21 +03001745> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-sync-05.kt)
Roman Elizarov1e459602017-02-27 11:05:17 +03001746
1747<!--- TEST ARBITRARY_TIME
1748Completed 1000000 actions in xxx ms
1749Counter = 1000000
1750-->
1751
1752This now works much faster and produces correct result.
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001753
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001754### Mutual exclusion
1755
1756Mutual exclusion solution to the problem is to protect all modifications of the shared state with a _critical section_
1757that is never executed concurrently. In a blocking world you'd typically use `synchronized` or `ReentrantLock` for that.
1758Coroutine's alternative is called [Mutex]. It has [lock][Mutex.lock] and [unlock][Mutex.unlock] functions to
1759delimit a critical section. The key difference is that `Mutex.lock` is a suspending function. It does not block a thread.
1760
1761```kotlin
1762val mutex = Mutex()
1763var counter = 0
1764
1765fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov1e459602017-02-27 11:05:17 +03001766 massiveRun(CommonPool) {
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001767 mutex.lock()
1768 try { counter++ }
1769 finally { mutex.unlock() }
1770 }
1771 println("Counter = $counter")
1772}
1773```
1774
Roman Elizarove8d79342017-08-29 15:21:21 +03001775> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-sync-06.kt)
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001776
Roman Elizarov1e459602017-02-27 11:05:17 +03001777<!--- TEST ARBITRARY_TIME
1778Completed 1000000 actions in xxx ms
1779Counter = 1000000
1780-->
1781
1782The locking in this example is fine-grained, so it pays the price. However, it is a good choice for some situations
1783where you absolutely must modify some shared state periodically, but there is no natural thread that this state
1784is confined to.
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001785
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001786### Actors
1787
1788An actor is a combination of a coroutine, the state that is confined and is encapsulated into this coroutine,
1789and a channel to communicate with other coroutines. A simple actor can be written as a function,
1790but an actor with a complex state is better suited for a class.
1791
Roman Elizarovc0e19f82017-02-27 11:59:14 +03001792There is an [actor] coroutine builder that conveniently combines actor's mailbox channel into its
1793scope to receive messages from and combines the send channel into the resulting job object, so that a
1794single reference to the actor can be carried around as its handle.
1795
Roman Elizarov256812a2017-07-22 01:00:30 +03001796The first step of using an actor is to define a class of messages that an actor is going to process.
1797Kotlin's [sealed classes](https://kotlinlang.org/docs/reference/sealed-classes.html) are well suited for that purpose.
1798We define `CounterMsg` sealed class with `IncCounter` message to increment a counter and `GetCounter` message
1799to get its value. The later needs to send a response. A [CompletableDeferred] communication
1800primitive, that represents a single value that will be known (communicated) in the future,
1801is used here for that purpose.
1802
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001803```kotlin
1804// Message types for counterActor
1805sealed class CounterMsg
1806object IncCounter : CounterMsg() // one-way message to increment counter
Roman Elizarov256812a2017-07-22 01:00:30 +03001807class GetCounter(val response: CompletableDeferred<Int>) : CounterMsg() // a request with reply
1808```
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001809
Roman Elizarov256812a2017-07-22 01:00:30 +03001810Then we define a function that launches an actor using an [actor] coroutine builder:
1811
1812```kotlin
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001813// This function launches a new counter actor
Roman Elizarovc0e19f82017-02-27 11:59:14 +03001814fun counterActor() = actor<CounterMsg>(CommonPool) {
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001815 var counter = 0 // actor state
Roman Elizarovc0e19f82017-02-27 11:59:14 +03001816 for (msg in channel) { // iterate over incoming messages
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001817 when (msg) {
1818 is IncCounter -> counter++
Roman Elizarov256812a2017-07-22 01:00:30 +03001819 is GetCounter -> msg.response.complete(counter)
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001820 }
1821 }
1822}
Roman Elizarov256812a2017-07-22 01:00:30 +03001823```
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001824
Roman Elizarov256812a2017-07-22 01:00:30 +03001825The main code is straightforward:
1826
1827```kotlin
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001828fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarovc0e19f82017-02-27 11:59:14 +03001829 val counter = counterActor() // create the actor
Roman Elizarov1e459602017-02-27 11:05:17 +03001830 massiveRun(CommonPool) {
Roman Elizarovc0e19f82017-02-27 11:59:14 +03001831 counter.send(IncCounter)
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001832 }
Roman Elizarov256812a2017-07-22 01:00:30 +03001833 // send a message to get a counter value from an actor
1834 val response = CompletableDeferred<Int>()
Roman Elizarovc0e19f82017-02-27 11:59:14 +03001835 counter.send(GetCounter(response))
Roman Elizarov256812a2017-07-22 01:00:30 +03001836 println("Counter = ${response.await()}")
Roman Elizarovc0e19f82017-02-27 11:59:14 +03001837 counter.close() // shutdown the actor
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001838}
1839```
1840
Roman Elizarove8d79342017-08-29 15:21:21 +03001841> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-sync-07.kt)
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001842
Roman Elizarov1e459602017-02-27 11:05:17 +03001843<!--- TEST ARBITRARY_TIME
1844Completed 1000000 actions in xxx ms
1845Counter = 1000000
1846-->
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001847
Roman Elizarovc0e19f82017-02-27 11:59:14 +03001848It does not matter (for correctness) what context the actor itself is executed in. An actor is
Roman Elizarovf5bc0472017-02-22 11:38:13 +03001849a coroutine and a coroutine is executed sequentially, so confinement of the state to the specific coroutine
1850works as a solution to the problem of shared mutable state.
1851
Roman Elizarovc0e19f82017-02-27 11:59:14 +03001852Actor is more efficient than locking under load, because in this case it always has work to do and it does not
1853have to switch to a different context at all.
1854
1855> Note, that an [actor] coroutine builder is a dual of [produce] coroutine builder. An actor is associated
1856 with the channel that it receives messages from, while a producer is associated with the channel that it
1857 sends elements to.
Roman Elizarov1e459602017-02-27 11:05:17 +03001858
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001859## Select expression
1860
Roman Elizarova84730b2017-02-22 11:58:50 +03001861Select expression makes it possible to await multiple suspending functions simultaneously and _select_
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001862the first one that becomes available.
1863
1864<!--- INCLUDE .*/example-select-([0-9]+).kt
1865import kotlinx.coroutines.experimental.channels.*
1866import kotlinx.coroutines.experimental.selects.*
1867-->
1868
1869### Selecting from channels
1870
Roman Elizarov57857202017-03-02 23:17:25 +03001871Let us have two producers of strings: `fizz` and `buzz`. The `fizz` produces "Fizz" string every 300 ms:
1872
1873<!--- INCLUDE .*/example-select-01.kt
1874import kotlin.coroutines.experimental.CoroutineContext
1875-->
1876
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001877```kotlin
Roman Elizarov57857202017-03-02 23:17:25 +03001878fun fizz(context: CoroutineContext) = produce<String>(context) {
1879 while (true) { // sends "Fizz" every 300 ms
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001880 delay(300)
1881 send("Fizz")
1882 }
1883}
1884```
1885
Roman Elizarov57857202017-03-02 23:17:25 +03001886And the `buzz` produces "Buzz!" string every 500 ms:
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001887
1888```kotlin
Roman Elizarov57857202017-03-02 23:17:25 +03001889fun buzz(context: CoroutineContext) = produce<String>(context) {
1890 while (true) { // sends "Buzz!" every 500 ms
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001891 delay(500)
1892 send("Buzz!")
1893 }
1894}
1895```
1896
1897Using [receive][ReceiveChannel.receive] suspending function we can receive _either_ from one channel or the
1898other. But [select] expression allows us to receive from _both_ simultaneously using its
Roman Elizarov8a5564d2017-09-06 18:48:22 +03001899[onReceive][ReceiveChannel.onReceive] clauses:
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001900
1901```kotlin
Roman Elizarov57857202017-03-02 23:17:25 +03001902suspend fun selectFizzBuzz(fizz: ReceiveChannel<String>, buzz: ReceiveChannel<String>) {
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001903 select<Unit> { // <Unit> means that this select expression does not produce any result
1904 fizz.onReceive { value -> // this is the first select clause
1905 println("fizz -> '$value'")
1906 }
1907 buzz.onReceive { value -> // this is the second select clause
1908 println("buzz -> '$value'")
1909 }
1910 }
1911}
1912```
1913
Roman Elizarov57857202017-03-02 23:17:25 +03001914Let us run it all seven times:
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001915
1916```kotlin
1917fun main(args: Array<String>) = runBlocking<Unit> {
Roman Elizarov43e3af72017-07-21 16:01:31 +03001918 val fizz = fizz(coroutineContext)
1919 val buzz = buzz(coroutineContext)
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001920 repeat(7) {
Roman Elizarov57857202017-03-02 23:17:25 +03001921 selectFizzBuzz(fizz, buzz)
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001922 }
1923}
1924```
1925
Roman Elizarove8d79342017-08-29 15:21:21 +03001926> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-select-01.kt)
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001927
1928The result of this code is:
1929
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001930```text
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001931fizz -> 'Fizz'
1932buzz -> 'Buzz!'
1933fizz -> 'Fizz'
1934fizz -> 'Fizz'
1935buzz -> 'Buzz!'
1936fizz -> 'Fizz'
1937buzz -> 'Buzz!'
1938```
1939
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001940<!--- TEST -->
1941
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001942### Selecting on close
1943
Roman Elizarov8a5564d2017-09-06 18:48:22 +03001944The [onReceive][ReceiveChannel.onReceive] clause in `select` fails when the channel is closed and the corresponding
1945`select` throws an exception. We can use [onReceiveOrNull][ReceiveChannel.onReceiveOrNull] clause to perform a
Roman Elizarova84730b2017-02-22 11:58:50 +03001946specific action when the channel is closed. The following example also shows that `select` is an expression that returns
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001947the result of its selected clause:
1948
1949```kotlin
1950suspend fun selectAorB(a: ReceiveChannel<String>, b: ReceiveChannel<String>): String =
1951 select<String> {
1952 a.onReceiveOrNull { value ->
1953 if (value == null)
1954 "Channel 'a' is closed"
1955 else
1956 "a -> '$value'"
1957 }
1958 b.onReceiveOrNull { value ->
1959 if (value == null)
1960 "Channel 'b' is closed"
1961 else
1962 "b -> '$value'"
1963 }
1964 }
1965```
1966
Roman Elizarova84730b2017-02-22 11:58:50 +03001967Let's use it with channel `a` that produces "Hello" string four times and
1968channel `b` that produces "World" four times:
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001969
1970```kotlin
1971fun main(args: Array<String>) = runBlocking<Unit> {
1972 // we are using the context of the main thread in this example for predictability ...
Roman Elizarov43e3af72017-07-21 16:01:31 +03001973 val a = produce<String>(coroutineContext) {
Roman Elizarova84730b2017-02-22 11:58:50 +03001974 repeat(4) { send("Hello $it") }
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001975 }
Roman Elizarov43e3af72017-07-21 16:01:31 +03001976 val b = produce<String>(coroutineContext) {
Roman Elizarova84730b2017-02-22 11:58:50 +03001977 repeat(4) { send("World $it") }
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001978 }
1979 repeat(8) { // print first eight results
1980 println(selectAorB(a, b))
1981 }
1982}
1983```
1984
Roman Elizarove8d79342017-08-29 15:21:21 +03001985> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-select-02.kt)
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001986
Roman Elizarova84730b2017-02-22 11:58:50 +03001987The result of this code is quite interesting, so we'll analyze it in mode detail:
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001988
Roman Elizarov731f0ad2017-02-22 20:48:45 +03001989```text
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03001990a -> 'Hello 0'
1991a -> 'Hello 1'
1992b -> 'World 0'
1993a -> 'Hello 2'
1994a -> 'Hello 3'
1995b -> 'World 1'
1996Channel 'a' is closed
1997Channel 'a' is closed
1998```
1999
Roman Elizarov731f0ad2017-02-22 20:48:45 +03002000<!--- TEST -->
2001
Roman Elizarova84730b2017-02-22 11:58:50 +03002002There are couple of observations to make out of it.
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002003
2004First of all, `select` is _biased_ to the first clause. When several clauses are selectable at the same time,
2005the first one among them gets selected. Here, both channels are constantly producing strings, so `a` channel,
Roman Elizarova84730b2017-02-22 11:58:50 +03002006being the first clause in select, wins. However, because we are using unbuffered channel, the `a` gets suspended from
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002007time to time on its [send][SendChannel.send] invocation and gives a chance for `b` to send, too.
2008
Roman Elizarov8a5564d2017-09-06 18:48:22 +03002009The second observation, is that [onReceiveOrNull][ReceiveChannel.onReceiveOrNull] gets immediately selected when the
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002010channel is already closed.
2011
2012### Selecting to send
2013
Roman Elizarov8a5564d2017-09-06 18:48:22 +03002014Select expression has [onSend][SendChannel.onSend] clause that can be used for a great good in combination
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002015with a biased nature of selection.
2016
Roman Elizarova84730b2017-02-22 11:58:50 +03002017Let us write an example of producer of integers that sends its values to a `side` channel when
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002018the consumers on its primary channel cannot keep up with it:
2019
2020```kotlin
2021fun produceNumbers(side: SendChannel<Int>) = produce<Int>(CommonPool) {
2022 for (num in 1..10) { // produce 10 numbers from 1 to 10
2023 delay(100) // every 100 ms
2024 select<Unit> {
Roman Elizarova84730b2017-02-22 11:58:50 +03002025 onSend(num) {} // Send to the primary channel
2026 side.onSend(num) {} // or to the side channel
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002027 }
2028 }
2029}
2030```
2031
2032Consumer is going to be quite slow, taking 250 ms to process each number:
2033
2034```kotlin
2035fun main(args: Array<String>) = runBlocking<Unit> {
2036 val side = Channel<Int>() // allocate side channel
Roman Elizarov43e3af72017-07-21 16:01:31 +03002037 launch(coroutineContext) { // this is a very fast consumer for the side channel
Roman Elizarov86349be2017-03-17 16:47:37 +03002038 side.consumeEach { println("Side channel has $it") }
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002039 }
Roman Elizarov86349be2017-03-17 16:47:37 +03002040 produceNumbers(side).consumeEach {
2041 println("Consuming $it")
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002042 delay(250) // let us digest the consumed number properly, do not hurry
2043 }
2044 println("Done consuming")
2045}
2046```
2047
Roman Elizarove8d79342017-08-29 15:21:21 +03002048> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-select-03.kt)
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002049
2050So let us see what happens:
2051
Roman Elizarov731f0ad2017-02-22 20:48:45 +03002052```text
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002053Consuming 1
2054Side channel has 2
2055Side channel has 3
2056Consuming 4
2057Side channel has 5
2058Side channel has 6
2059Consuming 7
2060Side channel has 8
2061Side channel has 9
2062Consuming 10
2063Done consuming
2064```
2065
Roman Elizarov731f0ad2017-02-22 20:48:45 +03002066<!--- TEST -->
2067
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002068### Selecting deferred values
2069
Roman Elizarov8a5564d2017-09-06 18:48:22 +03002070Deferred values can be selected using [onAwait][Deferred.onAwait] clause.
Roman Elizarova84730b2017-02-22 11:58:50 +03002071Let us start with an async function that returns a deferred string value after
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002072a random delay:
2073
2074<!--- INCLUDE .*/example-select-04.kt
2075import java.util.*
2076-->
2077
2078```kotlin
2079fun asyncString(time: Int) = async(CommonPool) {
2080 delay(time.toLong())
2081 "Waited for $time ms"
2082}
2083```
2084
Roman Elizarova84730b2017-02-22 11:58:50 +03002085Let us start a dozen of them with a random delay.
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002086
2087```kotlin
2088fun asyncStringsList(): List<Deferred<String>> {
2089 val random = Random(3)
Roman Elizarova84730b2017-02-22 11:58:50 +03002090 return List(12) { asyncString(random.nextInt(1000)) }
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002091}
2092```
2093
Roman Elizarova84730b2017-02-22 11:58:50 +03002094Now the main function awaits for the first of them to complete and counts the number of deferred values
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002095that are still active. Note, that we've used here the fact that `select` expression is a Kotlin DSL,
Roman Elizarova84730b2017-02-22 11:58:50 +03002096so we can provide clauses for it using an arbitrary code. In this case we iterate over a list
2097of deferred values to provide `onAwait` clause for each deferred value.
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002098
2099```kotlin
2100fun main(args: Array<String>) = runBlocking<Unit> {
2101 val list = asyncStringsList()
2102 val result = select<String> {
2103 list.withIndex().forEach { (index, deferred) ->
2104 deferred.onAwait { answer ->
2105 "Deferred $index produced answer '$answer'"
2106 }
2107 }
2108 }
2109 println(result)
Roman Elizarov7c864d82017-02-27 10:17:50 +03002110 val countActive = list.count { it.isActive }
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002111 println("$countActive coroutines are still active")
2112}
2113```
2114
Roman Elizarove8d79342017-08-29 15:21:21 +03002115> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-select-04.kt)
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002116
2117The output is:
2118
Roman Elizarov731f0ad2017-02-22 20:48:45 +03002119```text
Roman Elizarova84730b2017-02-22 11:58:50 +03002120Deferred 4 produced answer 'Waited for 128 ms'
Roman Elizarovd4dcbe22017-02-22 09:57:46 +0300212111 coroutines are still active
2122```
2123
Roman Elizarov731f0ad2017-02-22 20:48:45 +03002124<!--- TEST -->
2125
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002126### Switch over a channel of deferred values
2127
Roman Elizarova84730b2017-02-22 11:58:50 +03002128Let us write a channel producer function that consumes a channel of deferred string values, waits for each received
2129deferred value, but only until the next deferred value comes over or the channel is closed. This example puts together
Roman Elizarov8a5564d2017-09-06 18:48:22 +03002130[onReceiveOrNull][ReceiveChannel.onReceiveOrNull] and [onAwait][Deferred.onAwait] clauses in the same `select`:
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002131
2132```kotlin
2133fun switchMapDeferreds(input: ReceiveChannel<Deferred<String>>) = produce<String>(CommonPool) {
Roman Elizarova84730b2017-02-22 11:58:50 +03002134 var current = input.receive() // start with first received deferred value
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002135 while (isActive) { // loop while not cancelled/closed
2136 val next = select<Deferred<String>?> { // return next deferred value from this select or null
2137 input.onReceiveOrNull { update ->
2138 update // replaces next value to wait
2139 }
2140 current.onAwait { value ->
2141 send(value) // send value that current deferred has produced
2142 input.receiveOrNull() // and use the next deferred from the input channel
2143 }
2144 }
2145 if (next == null) {
2146 println("Channel was closed")
2147 break // out of loop
2148 } else {
2149 current = next
2150 }
2151 }
2152}
2153```
2154
2155To test it, we'll use a simple async function that resolves to a specified string after a specified time:
2156
2157```kotlin
2158fun asyncString(str: String, time: Long) = async(CommonPool) {
2159 delay(time)
2160 str
2161}
2162```
2163
2164The main function just launches a coroutine to print results of `switchMapDeferreds` and sends some test
2165data to it:
2166
2167```kotlin
2168fun main(args: Array<String>) = runBlocking<Unit> {
2169 val chan = Channel<Deferred<String>>() // the channel for test
Roman Elizarov43e3af72017-07-21 16:01:31 +03002170 launch(coroutineContext) { // launch printing coroutine
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002171 for (s in switchMapDeferreds(chan))
2172 println(s) // print each received string
2173 }
2174 chan.send(asyncString("BEGIN", 100))
2175 delay(200) // enough time for "BEGIN" to be produced
2176 chan.send(asyncString("Slow", 500))
Roman Elizarova84730b2017-02-22 11:58:50 +03002177 delay(100) // not enough time to produce slow
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002178 chan.send(asyncString("Replace", 100))
Roman Elizarova84730b2017-02-22 11:58:50 +03002179 delay(500) // give it time before the last one
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002180 chan.send(asyncString("END", 500))
2181 delay(1000) // give it time to process
Roman Elizarova84730b2017-02-22 11:58:50 +03002182 chan.close() // close the channel ...
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002183 delay(500) // and wait some time to let it finish
2184}
2185```
2186
Roman Elizarove8d79342017-08-29 15:21:21 +03002187> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-select-05.kt)
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002188
2189The result of this code:
2190
Roman Elizarov731f0ad2017-02-22 20:48:45 +03002191```text
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002192BEGIN
2193Replace
2194END
2195Channel was closed
2196```
2197
Roman Elizarov731f0ad2017-02-22 20:48:45 +03002198<!--- TEST -->
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002199
Roman Elizarov8db17332017-03-09 12:40:45 +03002200## Further reading
2201
2202* [Guide to UI programming with coroutines](ui/coroutines-guide-ui.md)
Roman Elizarov8a4a8e12017-03-09 19:52:58 +03002203* [Guide to reactive streams with coroutines](reactive/coroutines-guide-reactive.md)
Roman Elizarov8db17332017-03-09 12:40:45 +03002204* [Coroutines design document (KEEP)](https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md)
2205* [Full kotlinx.coroutines API reference](http://kotlin.github.io/kotlinx.coroutines)
2206
Roman Elizarove7e2ad12017-05-17 14:47:31 +03002207<!--- MODULE kotlinx-coroutines-core -->
Roman Elizarove0c817d2017-02-10 10:22:01 +03002208<!--- INDEX kotlinx.coroutines.experimental -->
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002209[launch]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/launch.html
2210[delay]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/delay.html
2211[runBlocking]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/run-blocking.html
Roman Elizarove82dee72017-08-18 16:49:09 +03002212[Job]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-job/index.html
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002213[CancellationException]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-cancellation-exception.html
2214[yield]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/yield.html
Roman Elizarovbff3f372017-03-01 18:12:27 +03002215[CoroutineScope.isActive]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-scope/is-active.html
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002216[CoroutineScope]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-scope/index.html
2217[run]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/run.html
2218[NonCancellable]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-non-cancellable/index.html
2219[withTimeout]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/with-timeout.html
Roman Elizarov63f6ea22017-09-06 18:42:34 +03002220[withTimeoutOrNull]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/with-timeout-or-null.html
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002221[async]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/async.html
2222[Deferred]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html
Roman Elizarovecda27f2017-04-06 23:06:26 +03002223[CoroutineStart.LAZY]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-start/-l-a-z-y.html
Roman Elizarovbff3f372017-03-01 18:12:27 +03002224[Deferred.await]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/await.html
2225[Job.start]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-job/start.html
Roman Elizarov419a6c82017-02-09 18:36:22 +03002226[CommonPool]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-common-pool/index.html
2227[CoroutineDispatcher]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-dispatcher/index.html
Roman Elizarov43e3af72017-07-21 16:01:31 +03002228[CoroutineScope.coroutineContext]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-scope/coroutine-context.html
Roman Elizarov419a6c82017-02-09 18:36:22 +03002229[Unconfined]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-unconfined/index.html
Roman Elizarov419a6c82017-02-09 18:36:22 +03002230[newCoroutineContext]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/new-coroutine-context.html
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002231[CoroutineName]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-name/index.html
Roman Elizarovbff3f372017-03-01 18:12:27 +03002232[Job.cancel]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-job/cancel.html
Roman Elizarove82dee72017-08-18 16:49:09 +03002233[CompletableDeferred]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-completable-deferred/index.html
Roman Elizarov8a5564d2017-09-06 18:48:22 +03002234[Deferred.onAwait]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/on-await.html
Roman Elizarovf5bc0472017-02-22 11:38:13 +03002235<!--- INDEX kotlinx.coroutines.experimental.sync -->
Roman Elizarove82dee72017-08-18 16:49:09 +03002236[Mutex]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.sync/-mutex/index.html
Roman Elizarovbff3f372017-03-01 18:12:27 +03002237[Mutex.lock]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.sync/-mutex/lock.html
2238[Mutex.unlock]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.sync/-mutex/unlock.html
Roman Elizarove0c817d2017-02-10 10:22:01 +03002239<!--- INDEX kotlinx.coroutines.experimental.channels -->
Roman Elizarove82dee72017-08-18 16:49:09 +03002240[Channel]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/-channel/index.html
Roman Elizarovbff3f372017-03-01 18:12:27 +03002241[SendChannel.send]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/-send-channel/send.html
2242[ReceiveChannel.receive]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/-receive-channel/receive.html
2243[SendChannel.close]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/-send-channel/close.html
Roman Elizarova5e653f2017-02-13 13:49:55 +03002244[produce]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/produce.html
Roman Elizarov86349be2017-03-17 16:47:37 +03002245[consumeEach]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/consume-each.html
Roman Elizarovc0e19f82017-02-27 11:59:14 +03002246[actor]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/actor.html
Roman Elizarov8a5564d2017-09-06 18:48:22 +03002247[ReceiveChannel.onReceive]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/-receive-channel/on-receive.html
2248[ReceiveChannel.onReceiveOrNull]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/-receive-channel/on-receive-or-null.html
2249[SendChannel.onSend]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.channels/-send-channel/on-send.html
Roman Elizarovd4dcbe22017-02-22 09:57:46 +03002250<!--- INDEX kotlinx.coroutines.experimental.selects -->
2251[select]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental.selects/select.html
Roman Elizarov419a6c82017-02-09 18:36:22 +03002252<!--- END -->