blob: db1905a4ea237d0cf2ef6882638de25b2e4b2d0a [file] [log] [blame] [view]
Roman Elizarovf16fd272017-02-07 11:26:00 +03001<!---
2
3Copyright 2016-2017 JetBrains s.r.o.
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16
17-->
18
Roman Elizarov7deefb82017-01-31 10:33:17 +030019# Guide to kotlinx.coroutines by example
20
21This is a short guide on core features of `kotlinx.coroutines` with a series of examples.
22
Roman Elizarov1293ccd2017-02-01 18:49:54 +030023## Table of contents
24
Roman Elizarovfa7723e2017-02-06 11:17:51 +030025<!--- TOC -->
26
Roman Elizarov1293ccd2017-02-01 18:49:54 +030027* [Coroutine basics](#coroutine-basics)
28 * [Your first coroutine](#your-first-coroutine)
29 * [Bridging blocking and non-blocking worlds](#bridging-blocking-and-non-blocking-worlds)
30 * [Waiting for a job](#waiting-for-a-job)
31 * [Extract function refactoring](#extract-function-refactoring)
32 * [Coroutines ARE light-weight](#coroutines-are-light-weight)
33 * [Coroutines are like daemon threads](#coroutines-are-like-daemon-threads)
34* [Cancellation and timeouts](#cancellation-and-timeouts)
35 * [Cancelling coroutine execution](#cancelling-coroutine-execution)
36 * [Cancellation is cooperative](#cancellation-is-cooperative)
37 * [Making computation code cancellable](#making-computation-code-cancellable)
38 * [Closing resources with finally](#closing-resources-with-finally)
39 * [Run non-cancellable block](#run-non-cancellable-block)
40 * [Timeout](#timeout)
41* [Composing suspending functions](#composing-suspending-functions)
42 * [Sequential by default](#sequential-by-default)
43 * [Concurrent using deferred value](#concurrent-using-deferred-value)
44 * [Lazily deferred value](#lazily-deferred-value)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +030045* [Coroutine context and dispatchers](#coroutine-context-and-dispatchers)
Roman Elizarovfa7723e2017-02-06 11:17:51 +030046 * [Dispatchers and threads](#dispatchers-and-threads)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +030047 * [Unconfined vs confined dispatcher](#unconfined-vs-confined-dispatcher)
48 * [Debugging coroutines and threads](#debugging-coroutines-and-threads)
49 * [Jumping between threads](#jumping-between-threads)
50 * [Job in the context](#job-in-the-context)
51 * [Children of a coroutine](#children-of-a-coroutine)
52 * [Combining contexts](#combining-contexts)
53 * [Naming coroutines for debugging](#naming-coroutines-for-debugging)
Roman Elizarovb7721cf2017-02-03 19:23:08 +030054* [Channels](#channels)
55 * [Channel basics](#channel-basics)
56 * [Closing and iteration over channels](#closing-and-iteration-over-channels)
57 * [Building channel producers](#building-channel-producers)
58 * [Pipelines](#pipelines)
59 * [Prime numbers with pipeline](#prime-numbers-with-pipeline)
60 * [Fan-out](#fan-out)
61 * [Fan-in](#fan-in)
62 * [Buffered channels](#buffered-channels)
Roman Elizarovfa7723e2017-02-06 11:17:51 +030063
Roman Elizarovb3d55a52017-02-03 12:47:21 +030064<!--- KNIT kotlinx-coroutines-core/src/test/kotlin/guide/.*\.kt -->
Roman Elizarov1293ccd2017-02-01 18:49:54 +030065
Roman Elizarovfa7723e2017-02-06 11:17:51 +030066<!--- INCLUDE .*/example-([a-z]+)-([0-9]+)\.kt
Roman Elizarovf16fd272017-02-07 11:26:00 +030067/*
68 * Copyright 2016-2017 JetBrains s.r.o.
69 *
70 * Licensed under the Apache License, Version 2.0 (the "License");
71 * you may not use this file except in compliance with the License.
72 * You may obtain a copy of the License at
73 *
74 * http://www.apache.org/licenses/LICENSE-2.0
75 *
76 * Unless required by applicable law or agreed to in writing, software
77 * distributed under the License is distributed on an "AS IS" BASIS,
78 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79 * See the License for the specific language governing permissions and
80 * limitations under the License.
81 */
82
Roman Elizarovb3d55a52017-02-03 12:47:21 +030083// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
Roman Elizarovfa7723e2017-02-06 11:17:51 +030084package guide.$$1.example$$2
Roman Elizarovb3d55a52017-02-03 12:47:21 +030085
86import kotlinx.coroutines.experimental.*
87-->
88
Roman Elizarov1293ccd2017-02-01 18:49:54 +030089## Coroutine basics
90
91This section covers basic coroutine concepts.
92
93### Your first coroutine
Roman Elizarov7deefb82017-01-31 10:33:17 +030094
95Run the following code:
96
97```kotlin
98fun main(args: Array<String>) {
99 launch(CommonPool) { // create new coroutine in common thread pool
100 delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
101 println("World!") // print after delay
102 }
103 println("Hello,") // main function continues while coroutine is delayed
104 Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
105}
106```
107
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300108> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-01.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300109
110Run this code:
111
112```
113Hello,
114World!
115```
116
117Essentially, coroutines are light-weight threads. You can achieve the same result replacing
118`launch(CommonPool) { ... }` with `thread { ... }` and `delay(...)` with `Thread.sleep(...)`. Try it.
119
120If you start by replacing `launch(CommonPool)` by `thread`, the compiler produces the following error:
121
122```
123Error: Kotlin: Suspend functions are only allowed to be called from a coroutine or another suspend function
124```
125
126That is because `delay` is a special _suspending function_ that does not block a thread, but _suspends_
127coroutine and it can be only used from a coroutine.
128
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300129### Bridging blocking and non-blocking worlds
Roman Elizarov7deefb82017-01-31 10:33:17 +0300130
131The first example mixes _non-blocking_ `delay(...)` and _blocking_ `Thread.sleep(...)` in the same
132code of `main` function. It is easy to get lost. Let's cleanly separate blocking and non-blocking
133worlds by using `runBlocking { ... }`:
134
135```kotlin
136fun main(args: Array<String>) = runBlocking<Unit> { // start main coroutine
137 launch(CommonPool) { // create new coroutine in common thread pool
138 delay(1000L)
139 println("World!")
140 }
141 println("Hello,") // main coroutine continues while child is delayed
142 delay(2000L) // non-blocking delay for 2 seconds to keep JVM alive
143}
144```
145
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300146> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-02.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300147
148The result is the same, but this code uses only non-blocking `delay`.
149
150`runBlocking { ... }` works as an adaptor that is used here to start the top-level main coroutine.
151The regular code outside of `runBlocking` _blocks_, until the coroutine inside `runBlocking` is active.
152
153This is also a way to write unit-tests for suspending functions:
154
155```kotlin
156class MyTest {
157 @Test
158 fun testMySuspendingFunction() = runBlocking<Unit> {
159 // here we can use suspending functions using any assertion style that we like
160 }
161}
162```
Roman Elizarovb3d55a52017-02-03 12:47:21 +0300163
164<!--- CLEAR -->
Roman Elizarov7deefb82017-01-31 10:33:17 +0300165
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300166### Waiting for a job
Roman Elizarov7deefb82017-01-31 10:33:17 +0300167
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300168Delaying for a time while another coroutine is working is not a good approach. Let's explicitly
169wait (in a non-blocking way) until the background job coroutine that we have launched is complete:
Roman Elizarov7deefb82017-01-31 10:33:17 +0300170
171```kotlin
172fun main(args: Array<String>) = runBlocking<Unit> {
173 val job = launch(CommonPool) { // create new coroutine and keep a reference to its Job
174 delay(1000L)
175 println("World!")
176 }
177 println("Hello,")
178 job.join() // wait until child coroutine completes
179}
180```
181
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300182> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-03.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300183
184Now 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 +0300185the background job in any way. Much better.
Roman Elizarov7deefb82017-01-31 10:33:17 +0300186
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300187### Extract function refactoring
Roman Elizarov7deefb82017-01-31 10:33:17 +0300188
189Let's extract the block of code inside `launch(CommonPool} { ... }` into a separate function. When you
190perform "Extract function" refactoring on this code you get a new function with `suspend` modifier.
191That is your first _suspending function_. Suspending functions can be used inside coroutines
192just like regular functions, but their additional feature is that they can, in turn,
193use other suspending functions, like `delay` in this example, to _suspend_ execution of a coroutine.
194
195```kotlin
196fun main(args: Array<String>) = runBlocking<Unit> {
197 val job = launch(CommonPool) { doWorld() }
198 println("Hello,")
199 job.join()
200}
201
202// this is your first suspending function
203suspend fun doWorld() {
204 delay(1000L)
205 println("World!")
206}
207```
208
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300209> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-04.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300210
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300211### Coroutines ARE light-weight
Roman Elizarov7deefb82017-01-31 10:33:17 +0300212
213Run the following code:
214
215```kotlin
216fun main(args: Array<String>) = runBlocking<Unit> {
217 val jobs = List(100_000) { // create a lot of coroutines and list their jobs
218 launch(CommonPool) {
219 delay(1000L)
220 print(".")
221 }
222 }
223 jobs.forEach { it.join() } // wait for all jobs to complete
224}
225```
226
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300227> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-05.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300228
229It starts 100K coroutines and, after a second, each coroutine prints a dot.
230Now, try that with threads. What would happen? (Most likely your code will produce some sort of out-of-memory error)
231
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300232### Coroutines are like daemon threads
Roman Elizarov7deefb82017-01-31 10:33:17 +0300233
234The following code launches a long-running coroutine that prints "I'm sleeping" twice a second and then
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300235returns from the main function after some delay:
Roman Elizarov7deefb82017-01-31 10:33:17 +0300236
237```kotlin
238fun main(args: Array<String>) = runBlocking<Unit> {
239 launch(CommonPool) {
240 repeat(1000) { i ->
241 println("I'm sleeping $i ...")
242 delay(500L)
243 }
244 }
245 delay(1300L) // just quit after delay
246}
247```
248
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300249> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-06.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300250
251You can run and see that it prints three lines and terminates:
252
253```
254I'm sleeping 0 ...
255I'm sleeping 1 ...
256I'm sleeping 2 ...
257```
258
259Active coroutines do not keep the process alive. They are like daemon threads.
260
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300261## Cancellation and timeouts
262
263This section covers coroutine cancellation and timeouts.
264
265### Cancelling coroutine execution
Roman Elizarov7deefb82017-01-31 10:33:17 +0300266
267In small application the return from "main" method might sound like a good idea to get all coroutines
268implicitly terminated. In a larger, long-running application, you need finer-grained control.
269The `launch` function returns a `Job` that can be used to cancel running coroutine:
270
271```kotlin
272fun main(args: Array<String>) = runBlocking<Unit> {
273 val job = launch(CommonPool) {
274 repeat(1000) { i ->
275 println("I'm sleeping $i ...")
276 delay(500L)
277 }
278 }
279 delay(1300L) // delay a bit
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300280 println("main: I'm tired of waiting!")
Roman Elizarov7deefb82017-01-31 10:33:17 +0300281 job.cancel() // cancels the job
282 delay(1300L) // delay a bit to ensure it was cancelled indeed
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300283 println("main: Now I can quit.")
Roman Elizarov7deefb82017-01-31 10:33:17 +0300284}
285```
286
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300287> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-01.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300288
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300289It produces the following output:
290
291```
292I'm sleeping 0 ...
293I'm sleeping 1 ...
294I'm sleeping 2 ...
295main: I'm tired of waiting!
296main: Now I can quit.
297```
298
299As soon as main invokes `job.cancel`, we don't see any output from the other coroutine because it was cancelled.
300
301### Cancellation is cooperative
Roman Elizarov7deefb82017-01-31 10:33:17 +0300302
Tair Rzayevaf734622017-02-01 22:30:16 +0200303Coroutine cancellation is _cooperative_. A coroutine code has to cooperate to be cancellable.
Roman Elizarov7deefb82017-01-31 10:33:17 +0300304All the suspending functions in `kotlinx.coroutines` are _cancellable_. They check for cancellation of
305coroutine and throw `CancellationException` when cancelled. However, if a coroutine is working in
306a computation and does not check for cancellation, then it cannot be cancelled, like the following
307example shows:
308
309```kotlin
310fun main(args: Array<String>) = runBlocking<Unit> {
311 val job = launch(CommonPool) {
312 var nextPrintTime = 0L
313 var i = 0
314 while (true) { // computation loop
315 val currentTime = System.currentTimeMillis()
316 if (currentTime >= nextPrintTime) {
317 println("I'm sleeping ${i++} ...")
318 nextPrintTime = currentTime + 500L
319 }
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 see if it was cancelled....
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 Elizarovfa7723e2017-02-06 11:17:51 +0300330> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-02.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300331
332Run it to see that it continues to print "I'm sleeping" even after cancellation.
333
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300334### Making computation code cancellable
Roman Elizarov7deefb82017-01-31 10:33:17 +0300335
336There are two approaches to making computation code cancellable. The first one is to periodically
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300337invoke a suspending function. There is a `yield` function that is a good choice for that purpose.
338The other one is to explicitly check the cancellation status. Let us try the later approach.
Roman Elizarov7deefb82017-01-31 10:33:17 +0300339
340Replace `while (true)` in the previous example with `while (isActive)` and rerun it.
341
Roman Elizarovb3d55a52017-02-03 12:47:21 +0300342```kotlin
343fun main(args: Array<String>) = runBlocking<Unit> {
344 val job = launch(CommonPool) {
345 var nextPrintTime = 0L
346 var i = 0
347 while (isActive) { // cancellable computation loop
348 val currentTime = System.currentTimeMillis()
349 if (currentTime >= nextPrintTime) {
350 println("I'm sleeping ${i++} ...")
351 nextPrintTime = currentTime + 500L
352 }
353 }
354 }
355 delay(1300L) // delay a bit
356 println("main: I'm tired of waiting!")
357 job.cancel() // cancels the job
358 delay(1300L) // delay a bit to see if it was cancelled....
359 println("main: Now I can quit.")
360}
361```
362
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300363> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-03.kt)
Roman Elizarov7deefb82017-01-31 10:33:17 +0300364
365As you can see, now this loop can be cancelled. `isActive` is a property that is available inside
366the code of coroutines via `CoroutineScope` object.
367
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300368### Closing resources with finally
369
370Cancellable suspending functions throw `CancellationException` on cancellation which can be handled in
371all the usual way. For example, the `try {...} finally {...}` and Kotlin `use` function execute their
372finalization actions normally when coroutine is cancelled:
373
374```kotlin
375fun main(args: Array<String>) = runBlocking<Unit> {
376 val job = launch(CommonPool) {
377 try {
378 repeat(1000) { i ->
379 println("I'm sleeping $i ...")
380 delay(500L)
381 }
382 } finally {
383 println("I'm running finally")
384 }
385 }
386 delay(1300L) // delay a bit
387 println("main: I'm tired of waiting!")
388 job.cancel() // cancels the job
389 delay(1300L) // delay a bit to ensure it was cancelled indeed
390 println("main: Now I can quit.")
391}
392```
393
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300394> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-04.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300395
396The example above produces the following output:
397
398```
399I'm sleeping 0 ...
400I'm sleeping 1 ...
401I'm sleeping 2 ...
402main: I'm tired of waiting!
403I'm running finally
404main: Now I can quit.
405```
406
407### Run non-cancellable block
408
409Any attempt to use a suspending function in the `finally` block of the previous example will cause
410`CancellationException`, because the coroutine running this code is cancelled. Usually, this is not a
411problem, since all well-behaving closing operations (closing a file, cancelling a job, or closing any kind of a
412communication channel) are usually non-blocking and do not involve any suspending functions. However, in the
413rare case when you need to suspend in the cancelled coroutine you can wrap the corresponding code in
414`run(NonCancellable) {...}` as the following example shows:
415
416```kotlin
417fun main(args: Array<String>) = runBlocking<Unit> {
418 val job = launch(CommonPool) {
419 try {
420 repeat(1000) { i ->
421 println("I'm sleeping $i ...")
422 delay(500L)
423 }
424 } finally {
425 run(NonCancellable) {
426 println("I'm running finally")
427 delay(1000L)
428 println("And I've just delayed for 1 sec because I'm non-cancellable")
429 }
430 }
431 }
432 delay(1300L) // delay a bit
433 println("main: I'm tired of waiting!")
434 job.cancel() // cancels the job
435 delay(1300L) // delay a bit to ensure it was cancelled indeed
436 println("main: Now I can quit.")
437}
438```
439
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300440> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-05.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300441
442### Timeout
443
444The most obvious reason to cancel coroutine execution in practice,
445is because its execution time has exceeded some timeout.
446While you can manually track the reference to the corresponding `job` and launch a separate coroutine to cancel
447the tracked one after delay, there is a ready to use `withTimeout(...) {...}` function that does it.
448Look at the following example:
449
450```kotlin
451fun main(args: Array<String>) = runBlocking<Unit> {
452 withTimeout(1300L) {
453 repeat(1000) { i ->
454 println("I'm sleeping $i ...")
455 delay(500L)
456 }
457 }
458}
459```
460
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300461> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-06.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300462
463It produces the following output:
464
465```
466I'm sleeping 0 ...
467I'm sleeping 1 ...
468I'm sleeping 2 ...
469Exception in thread "main" java.util.concurrent.CancellationException: Timed out waiting for 1300 MILLISECONDS
470```
471
472We have not seen the `CancellationException` stack trace printed on the console before. That is because
473inside a cancelled coroutine `CancellationException` is a considered a normal reason for coroutine completion.
474However, in this example we have used `withTimeout` right inside the `main` function.
475
476Because cancellation is just an exception, all the resources will be closed in a usual way.
477You can wrap the code with timeout in `try {...} catch (e: CancellationException) {...}` block if
478you need to do some additional action specifically on timeout.
479
480## Composing suspending functions
481
482This section covers various approaches to composition of suspending functions.
483
484### Sequential by default
485
486Assume that we have two suspending functions defined elsewhere that do something useful like some kind of
Roman Elizarovb7721cf2017-02-03 19:23:08 +0300487remote service call or computation. We just pretend they are useful, but actually each one just
488delays for a second for the purpose of this example:
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300489
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300490<!--- INCLUDE .*/example-compose-([0-9]+).kt
491import kotlin.system.measureTimeMillis
492-->
493
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300494```kotlin
495suspend fun doSomethingUsefulOne(): Int {
496 delay(1000L) // pretend we are doing something useful here
497 return 13
498}
499
500suspend fun doSomethingUsefulTwo(): Int {
501 delay(1000L) // pretend we are doing something useful here, too
502 return 29
503}
504```
505
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300506<!--- INCLUDE .*/example-compose-([0-9]+).kt -->
507
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300508What do we do if need to invoke them _sequentially_ -- first `doSomethingUsefulOne` _and then_
509`doSomethingUsefulTwo` and compute the sum of their results?
510In practise we do this if we use the results of the first function to make a decision on whether we need
511to invoke the second one or to decide on how to invoke it.
512
513We just use a normal sequential invocation, because the code in the coroutine, just like in the regular
514code, is _sequential_ by default. The following example demonstrates that by measuring the total
515time it takes to execute both suspending functions:
516
517```kotlin
518fun main(args: Array<String>) = runBlocking<Unit> {
519 val time = measureTimeMillis {
520 val one = doSomethingUsefulOne()
521 val two = doSomethingUsefulTwo()
522 println("The answer is ${one + two}")
523 }
524 println("Completed in $time ms")
525}
526```
527
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300528> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-01.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300529
530It produces something like this:
531
532```
533The answer is 42
534Completed in 2017 ms
535```
536
537### Concurrent using deferred value
538
539What if there are no dependencies between invocation of `doSomethingUsefulOne` and `doSomethingUsefulTwo` and
540we want to get the answer faster, by doing both _concurrently_? This is where `defer` comes to helps.
541
542Conceptually, `defer` is just like `launch`. It starts a separate coroutine which is a light-weight thread
543that works concurrently with all the other coroutines. The difference is that `launch` returns a `Job` and
544does not carry any resulting value, while `defer` returns a `Deferred` -- a kind of light-weight non-blocking future
545that represent a promise to provide result later. You can use `.await()` on a deferred value to get its eventual result,
546but `Deferred` is also a `Job`, so you can cancel it if needed.
547
548```kotlin
549fun main(args: Array<String>) = runBlocking<Unit> {
550 val time = measureTimeMillis {
551 val one = defer(CommonPool) { doSomethingUsefulOne() }
552 val two = defer(CommonPool) { doSomethingUsefulTwo() }
553 println("The answer is ${one.await() + two.await()}")
554 }
555 println("Completed in $time ms")
556}
557```
558
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300559> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-02.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300560
561It produces something like this:
562
563```
564The answer is 42
565Completed in 1017 ms
566```
567
568This is twice as fast, because we have concurrent execution of two coroutines.
569Note, that concurrency with coroutines is always explicit.
570
571### Lazily deferred value
572
573There is a lazy alternative to `defer` that is called `lazyDefer`. It is just like `defer`, but it
574starts coroutine only when its result is needed by some `await` or if a special `start` function
575is invoked. Run the following example:
576
577```kotlin
578fun main(args: Array<String>) = runBlocking<Unit> {
579 val time = measureTimeMillis {
580 val one = lazyDefer(CommonPool) { doSomethingUsefulOne() }
581 val two = lazyDefer(CommonPool) { doSomethingUsefulTwo() }
582 println("The answer is ${one.await() + two.await()}")
583 }
584 println("Completed in $time ms")
585}
586```
587
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300588> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-03.kt)
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300589
590It produces something like this:
591
592```
593The answer is 42
594Completed in 2017 ms
595```
596
597So, we are back to two sequential execution, because we _first_ await for the `one` deferred, _and then_ await
598for the second one. It is not the intended use-case for `lazyDefer`. It is designed as a replacement for
599the standard `lazy` function in cases when computation of the value involve suspending functions.
600
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300601## Coroutine context and dispatchers
602
603We've already seen `launch(CommonPool) {...}`, `defer(CommonPool) {...}`, `run(NonCancellable) {...}`, etc.
604In these code snippets `CommonPool` and `NonCancellable` are _coroutine contexts_.
605This section covers other available choices.
606
607### Dispatchers and threads
608
609Coroutine context includes a _coroutine dispatcher_ which determines what thread or threads
610the corresponding coroutine uses for its execution. Coroutine dispatcher can confine coroutine execution
611to a specific thread, dispatch it to a thread pool, or let it run unconfined. Try the following example:
612
613```kotlin
614fun main(args: Array<String>) = runBlocking<Unit> {
615 val jobs = arrayListOf<Job>()
616 jobs += launch(Unconfined) { // not confined -- will work with main thread
617 println(" 'Unconfined': I'm working in thread ${Thread.currentThread().name}")
618 }
619 jobs += launch(context) { // context of the parent, runBlocking coroutine
620 println(" 'context': I'm working in thread ${Thread.currentThread().name}")
621 }
622 jobs += launch(CommonPool) { // will get dispatched to ForkJoinPool.commonPool (or equivalent)
623 println(" 'CommonPool': I'm working in thread ${Thread.currentThread().name}")
624 }
625 jobs += launch(newSingleThreadContext("MyOwnThread")) { // will get its own new thread
626 println(" 'newSTC': I'm working in thread ${Thread.currentThread().name}")
627 }
628 jobs.forEach { it.join() }
629}
630```
631
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300632> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-context-01.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300633
634It produces the following output (maybe in different order):
635
636```
637 'Unconfined': I'm working in thread main
638 'CommonPool': I'm working in thread ForkJoinPool.commonPool-worker-1
639 'newSTC': I'm working in thread MyOwnThread
640 'context': I'm working in thread main
641```
642
643The difference between parent `context` and `Unconfied` context will be shown later.
644
645### Unconfined vs confined dispatcher
646
647The `Unconfined` coroutine dispatcher starts coroutine in the caller thread, but only until the
648first suspension point. After suspension it resumes in the thread that is fully determined by the
649suspending function that was invoked. Unconfined dispatcher is appropriate when coroutine does not
650consume CPU time nor updates any shared data (like UI) that is confined to a specific thread.
651
652On the other side, `context` property that is available inside the block of any coroutine
653via `CoroutineScope` interface, is a reference to a context of this particular coroutine.
654This way, a parent context can be inherited. The default context of `runBlocking`, in particular,
655is confined to be invoker thread, so inheriting it has the effect of confining execution to
656this thread with a predictable FIFO scheduling.
657
658```kotlin
659fun main(args: Array<String>) = runBlocking<Unit> {
660 val jobs = arrayListOf<Job>()
661 jobs += launch(Unconfined) { // not confined -- will work with main thread
662 println(" 'Unconfined': I'm working in thread ${Thread.currentThread().name}")
663 delay(1000)
664 println(" 'Unconfined': After delay in thread ${Thread.currentThread().name}")
665 }
666 jobs += launch(context) { // context of the parent, runBlocking coroutine
667 println(" 'context': I'm working in thread ${Thread.currentThread().name}")
668 delay(1000)
669 println(" 'context': After delay in thread ${Thread.currentThread().name}")
670 }
671 jobs.forEach { it.join() }
672}
673```
674
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300675> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-contest-02.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300676
677Produces the output:
678
679```
680 'Unconfined': I'm working in thread main
681 'context': I'm working in thread main
682 'Unconfined': After delay in thread kotlinx.coroutines.ScheduledExecutor
683 'context': After delay in thread main
684```
685
686So, the coroutine the had inherited `context` of `runBlocking {...}` continues to execute in the `main` thread,
687while the unconfined one had resumed in the scheduler thread that `delay` function is using.
688
689### Debugging coroutines and threads
690
691Coroutines can suspend on one thread and resume on another thread with `Unconfined` dispatcher or
692with a multi-threaded dispatcher like `CommonPool`. Even with a single-threaded dispatcher it might be hard to
693figure out what coroutine was doing what, where, and when. The common approach to debugging applications with
694threads is to print the thread name in the log file on each log statement. This feature is universally supported
695by logging frameworks. When using coroutines, the thread name alone does not give much of a context, so
696`kotlinx.coroutines` includes debugging facilities to make it easier.
697
698Run the following code with `-Dkotlinx.coroutines.debug` JVM option:
699
700```kotlin
701fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")
702
703fun main(args: Array<String>) = runBlocking<Unit> {
704 val a = defer(context) {
705 log("I'm computing a piece of the answer")
706 6
707 }
708 val b = defer(context) {
709 log("I'm computing another piece of the answer")
710 7
711 }
712 log("The answer is ${a.await() * b.await()}")
713}
714```
715
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300716> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-context-03.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300717
Roman Elizarovb7721cf2017-02-03 19:23:08 +0300718There are three coroutines. The main coroutine (#1) -- `runBlocking` one,
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300719and two coroutines computing deferred values `a` (#2) and `b` (#3).
720They are all executing in the context of `runBlocking` and are confined to the main thread.
721The output of this code is:
722
723```
724[main @coroutine#2] I'm computing a piece of the answer
725[main @coroutine#3] I'm computing another piece of the answer
726[main @coroutine#1] The answer is 42
727```
728
729The `log` function prints the name of the thread in square brackets and you can see, that it is the `main`
730thread, but the identifier of the currently executing coroutine is appended to it. This identifier
731is consecutively assigned to all created coroutines when debugging mode is turned on.
732
Roman Elizarovb7721cf2017-02-03 19:23:08 +0300733You can read more about debugging facilities in the documentation for `newCoroutineContext` function.
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300734
735### Jumping between threads
736
737Run the following code with `-Dkotlinx.coroutines.debug` JVM option:
738
739```kotlin
740fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")
741
742fun main(args: Array<String>) {
743 val ctx1 = newSingleThreadContext("Ctx1")
744 val ctx2 = newSingleThreadContext("Ctx2")
745 runBlocking(ctx1) {
746 log("Started in ctx1")
747 run(ctx2) {
748 log("Working in ctx2")
749 }
750 log("Back to ctx1")
751 }
752}
753```
754
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300755> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-context-04.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300756
757It demonstrates two new techniques. One is using `runBlocking` with an explicitly specified context, and
758the second one is using `run(context) {...}` to change a context of a coroutine while still staying in the
759same coroutine as you can see in the output below:
760
761```
762[Ctx1 @coroutine#1] Started in ctx1
763[Ctx2 @coroutine#1] Working in ctx2
764[Ctx1 @coroutine#1] Back to ctx1
765```
766
767### Job in the context
768
769The coroutine `Job` is part of its context. The coroutine can retrieve it from its own context
770using `context[Job]` expression:
771
772```kotlin
773fun main(args: Array<String>) = runBlocking<Unit> {
774 println("My job is ${context[Job]}")
775}
776```
777
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300778> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-context-05.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300779
780It produces
781
782```
783My job is BlockingCoroutine{isActive=true}
784```
785
786So, `isActive` in `CoroutineScope` is just a convenient shortcut for `context[Job]!!.isActive`.
787
788### Children of a coroutine
789
790When `context` of a coroutine is used to launch another coroutine, the `Job` of the new coroutine becomes
791a _child_ of the parent coroutine's job. When the parent coroutine is cancelled, all its children
792are recursively cancelled, too.
793
794```kotlin
795fun main(args: Array<String>) = runBlocking<Unit> {
796 // start a coroutine to process some kind of incoming request
797 val request = launch(CommonPool) {
798 // it spawns two other jobs, one with its separate context
799 val job1 = launch(CommonPool) {
800 println("job1: I have my own context and execute independently!")
801 delay(1000)
802 println("job1: I am not affected by cancellation of the request")
803 }
804 // and the other inherits the parent context
805 val job2 = launch(context) {
806 println("job2: I am a child of the request coroutine")
807 delay(1000)
808 println("job2: I will not execute this line if my parent request is cancelled")
809 }
810 // request completes when both its sub-jobs complete:
811 job1.join()
812 job2.join()
813 }
814 delay(500)
815 request.cancel() // cancel processing of the request
816 delay(1000) // delay a second to see what happens
817 println("main: Who has survived request cancellation?")
818}
819```
820
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300821> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-context-06.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300822
823The output of this code is:
824
825```
826job1: I have my own context and execute independently!
827job2: I am a child of the request coroutine
828job1: I am not affected by cancellation of the request
829main: Who has survived request cancellation?
830```
831
832### Combining contexts
833
834Coroutine context can be combined using `+` operator. The context on the right-hand side replaces relevant entries
835of the context on the left-hand side. For example, a `Job` of the parent coroutine can be inherited, while
836its dispatcher replaced:
837
838```kotlin
839fun main(args: Array<String>) = runBlocking<Unit> {
840 // start a coroutine to process some kind of incoming request
841 val request = launch(context) { // use the context of `runBlocking`
842 // spawns CPU-intensive child job in CommonPool !!!
843 val job = launch(context + CommonPool) {
844 println("job: I am a child of the request coroutine, but with a different dispatcher")
845 delay(1000)
846 println("job: I will not execute this line if my parent request is cancelled")
847 }
848 job.join() // request completes when its sub-job completes
849 }
850 delay(500)
851 request.cancel() // cancel processing of the request
852 delay(1000) // delay a second to see what happens
853 println("main: Who has survived request cancellation?")
854}
855```
856
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300857> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-context-07.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300858
859The expected outcome of this code is:
860
861```
862job: I am a child of the request coroutine, but with a different dispatcher
863main: Who has survived request cancellation?
864```
865
866### Naming coroutines for debugging
867
Roman Elizarovb7721cf2017-02-03 19:23:08 +0300868Automatically assigned ids are good when coroutines log often and you just need to correlate log records
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300869coming from the same coroutine. However, when coroutine is tied to the processing of a specific request
870or doing some specific background task, it is better to name it explicitly for debugging purposes.
871Coroutine name serves the same function as a thread name. It'll get displayed in the thread name that
872is executing this coroutine when debugging more is turned on.
873
874The following example demonstrates this concept:
875
876```kotlin
877fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")
878
879fun main(args: Array<String>) = runBlocking(CoroutineName("main")) {
880 log("Started main coroutine")
881 // run two background value computations
882 val v1 = defer(CommonPool + CoroutineName("v1coroutine")) {
883 log("Computing v1")
884 delay(500)
885 252
886 }
887 val v2 = defer(CommonPool + CoroutineName("v2coroutine")) {
888 log("Computing v2")
889 delay(1000)
890 6
891 }
892 log("The answer for v1 / v2 = ${v1.await() / v2.await()}")
893}
894```
895
Roman Elizarovfa7723e2017-02-06 11:17:51 +0300896> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-context-08.kt)
Roman Elizarov2f6d7c92017-02-03 15:16:07 +0300897
898The output it produces with `-Dkotlinx.coroutines.debug` JVM option is similar to:
899
900```
901[main @main#1] Started main coroutine
902[ForkJoinPool.commonPool-worker-1 @v1coroutine#2] Computing v1
903[ForkJoinPool.commonPool-worker-2 @v2coroutine#3] Computing v2
904[main @main#1] The answer for v1 / v2 = 42
905```
Roman Elizarov1293ccd2017-02-01 18:49:54 +0300906
Roman Elizarovb7721cf2017-02-03 19:23:08 +0300907## Channels
Roman Elizarov7deefb82017-01-31 10:33:17 +0300908
Roman Elizarovb7721cf2017-02-03 19:23:08 +0300909Deferred values provide a convenient way to transfer a single value between coroutines.
910Channels provide a way to transfer a stream of values.
911
912<!--- INCLUDE .*/example-channel-([0-9]+).kt
913import kotlinx.coroutines.experimental.channels.*
914-->
915
916### Channel basics
917
918A `Channel` is conceptually very similar to `BlockingQueue`. One key difference is that
919instead of a blocking `put` operation it has a suspending `send`, and instead of
920a blocking `take` operation it has a suspending `receive`.
921
922```kotlin
923fun main(args: Array<String>) = runBlocking<Unit> {
924 val channel = Channel<Int>()
925 launch(CommonPool) {
926 // this might be heavy CPU-consuming computation or async logic, we'll just send five squares
927 for (x in 1..5) channel.send(x * x)
928 }
929 // here we print five received integers:
930 repeat(5) { println(channel.receive()) }
931 println("Done!")
932}
933```
934
935> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-01.kt)
936
937### Closing and iteration over channels
938
939Unlike a queue, a channel can be closed to indicate that no more elements are coming.
940On the receiver side it is convenient to use a regular `for` loop to receive elements
941from the channel.
942
943Conceptually, a `close` is like sending a special close token to the channel.
944The iteration stops as soon as this close token is received, so there is a guarantee
945that all previously sent elements before the close are received:
946
947```kotlin
948fun main(args: Array<String>) = runBlocking<Unit> {
949 val channel = Channel<Int>()
950 launch(CommonPool) {
951 for (x in 1..5) channel.send(x * x)
952 channel.close() // we're done sending
953 }
954 // here we print received values using `for` loop (until the channel is closed)
955 for (y in channel) println(y)
956 println("Done!")
957}
958```
959
960> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-02.kt)
961
962### Building channel producers
963
964The pattern where a coroutine is producing a sequence of elements into a channel is quite common.
965You could abstract such a producer into a function that takes channel as its parameter, but this goes contrary
966to common sense that results must be returned from functions. Here is a convenience
967coroutine builder named `buildChannel` that makes it easy to do it right:
968
969```kotlin
970fun produceSquares() = buildChannel<Int>(CommonPool) {
971 for (x in 1..5) send(x * x)
972}
973
974fun main(args: Array<String>) = runBlocking<Unit> {
975 val squares = produceSquares()
976 for (y in squares) println(y)
977 println("Done!")
978}
979```
980
981> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-03.kt)
982
983### Pipelines
984
985Pipeline is a pattern where one coroutine is producing, possibly infinite, stream of values:
986
987```kotlin
988fun produceNumbers() = buildChannel<Int>(CommonPool) {
989 var x = 1
990 while (true) send(x++) // infinite stream of integers starting from 1
991}
992```
993
994And another coroutine or coroutines are receiving that stream, doing some processing, and sending the result.
995In the below example the numbers are just squared:
996
997```kotlin
998fun square(numbers: ReceiveChannel<Int>) = buildChannel<Int>(CommonPool) {
999 for (x in numbers) send(x * x)
1000}
1001```
1002
1003The main code starts and connects pipeline:
1004
1005```kotlin
1006fun main(args: Array<String>) = runBlocking<Unit> {
1007 val numbers = produceNumbers() // produces integers from 1 and on
1008 val squares = square(numbers) // squares integers
1009 for (i in 1..5) println(squares.receive()) // print first five
1010 println("Done!") // we are done
1011 squares.cancel() // need to cancel these coroutines in a larger app
1012 numbers.cancel()
1013}
1014```
1015
1016> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-04.kt)
1017
1018We don't have to cancel these coroutines in this example app, because
1019[coroutines are like daemon threads](#coroutines-are-like-daemon-threads),
1020but in a larger app we'll need to stop our pipeline if we don't need it anymore.
1021Alternatively, we could have run pipeline coroutines as
1022[children of a coroutine](#children-of-a-coroutine).
1023
1024### Prime numbers with pipeline
1025
1026Let's take pipelines to the extreme, with an example that generates prime numbers using a pipeline
1027of coroutines. We start with an infinite sequence of numbers. This time we introduce an
1028explicit context parameter, so that caller can control where our coroutines run:
1029
1030<!--- INCLUDE kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-05.kt
1031import kotlin.coroutines.experimental.CoroutineContext
1032-->
1033
1034```kotlin
1035fun numbersFrom(context: CoroutineContext, start: Int) = buildChannel<Int>(context) {
1036 var x = start
1037 while (true) send(x++) // infinite stream of integers from start
1038}
1039```
1040
1041The following pipeline stage filters an incoming stream of numbers, removing all the numbers
1042that are divisible by the given prime number:
1043
1044```kotlin
1045fun filter(context: CoroutineContext, numbers: ReceiveChannel<Int>, prime: Int) = buildChannel<Int>(context) {
1046 for (x in numbers) if (x % prime != 0) send(x)
1047}
1048```
1049
1050Now we build our pipeline by starting a stream of numbers from 2, taking a prime number from the current channel,
1051and launching new pipeline stage for each prime number found. The following example prints first ten prime numbers,
1052running the whole pipeline in the context of the main thread:
1053
1054```kotlin
1055fun main(args: Array<String>) = runBlocking<Unit> {
1056 var cur = numbersFrom(context, 2)
1057 for (i in 1..10) {
1058 val prime = cur.receive()
1059 println(prime)
1060 cur = filter(context, cur, prime)
1061 }
1062}
1063```
1064
1065> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-05.kt)
1066
1067The output of this code is:
1068
1069```
10702
10713
10725
10737
107411
107513
107617
107719
107823
107929
1080```
1081
1082### Fan-out
1083
1084Multiple coroutines may receive from the same channel, distributing work between themselves.
1085Let us start with a producer coroutine that is periodically producing integers
1086(ten numbers per second):
1087
1088```kotlin
1089fun produceNumbers() = buildChannel<Int>(CommonPool) {
1090 var x = 1 // start from 1
1091 while (true) {
1092 send(x++) // produce next
1093 delay(100) // wait 0.1s
1094 }
1095}
1096```
1097
1098Then we can have several processor coroutines. In this example, they just print their id and
1099received number:
1100
1101```kotlin
1102fun launchProcessor(id: Int, channel: ReceiveChannel<Int>) = launch(CommonPool) {
1103 while (true) {
1104 val x = channel.receive()
1105 println("Processor #$id received $x")
1106 }
1107}
1108```
1109
1110Now let us launch five processors and let them work for a second. See what happens:
1111
1112```kotlin
1113fun main(args: Array<String>) = runBlocking<Unit> {
1114 val producer = produceNumbers()
1115 repeat(5) { launchProcessor(it, producer) }
1116 delay(1000)
1117 producer.cancel() // cancel producer coroutine and thus kill them all
1118}
1119```
1120
1121> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-06.kt)
1122
1123The output will be similar to the the following one, albeit the processor ids that receive
1124each specific integer may be different:
1125
1126```
1127Processor #2 received 1
1128Processor #4 received 2
1129Processor #0 received 3
1130Processor #1 received 4
1131Processor #3 received 5
1132Processor #2 received 6
1133Processor #4 received 7
1134Processor #0 received 8
1135Processor #1 received 9
1136Processor #3 received 10
1137```
1138
1139Note, that cancelling a producer coroutine closes its channel, thus eventually terminating iteration
1140over the channel that processor coroutines are doing.
1141
1142### Fan-in
1143
1144Multiple coroutines may send to the same channel.
1145For example, let us have a channel of strings, and a suspending function that
1146repeatedly sends a specified string to this channel with a specified delay:
1147
1148```kotlin
1149suspend fun sendString(channel: SendChannel<String>, s: String, time: Long) {
1150 while (true) {
1151 delay(time)
1152 channel.send(s)
1153 }
1154}
1155```
1156
1157Now, let us see what happen if we launch a couple of coroutines sending strings
1158(in this example we launch them in the context of the main thread):
1159
1160```kotlin
1161fun main(args: Array<String>) = runBlocking<Unit> {
1162 val channel = Channel<String>()
1163 launch(context) { sendString(channel, "foo", 200L) }
1164 launch(context) { sendString(channel, "BAR!", 500L) }
1165 repeat(6) { // receive first six
1166 println(channel.receive())
1167 }
1168}
1169```
1170
1171> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-07.kt)
1172
1173The output is:
1174
1175```
1176foo
1177foo
1178BAR!
1179foo
1180foo
1181BAR!
1182```
1183
1184### Buffered channels
1185
1186The channels shown so far had no buffer. Unbuffered channels transfer elements when sender and receiver
1187meet each other (aka rendezvous). If send is invoked first, then it is suspended until receive is invoked,
1188if receive is invoked first, it is suspended until send is invoked.
1189
1190Both `Channel()` factory and `buildChanner{}` builder take an optional `capacity` parameter to
1191specify _buffer size_. Buffer allows senders to send multiple elements before suspending,
1192similar to the `BlockingQueue` with a specified capacity, which blocks when buffer is full.
1193
1194Take a look at the behavior of the following code:
1195
1196```kotlin
1197fun main(args: Array<String>) = runBlocking<Unit> {
1198 val channel = Channel<Int>(4) // create buffered channel
1199 launch(context) { // launch sender coroutine
1200 repeat(10) {
1201 println("Sending $it") // print before sending each element
1202 channel.send(it) // will suspend when buffer is full
1203 }
1204 }
1205 // don't receive anything... just wait....
1206 delay(1000)
1207}
1208```
1209
1210> You can get full code [here](kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-08.kt)
1211
1212It prints "sending" _five_ times using a buffered channel with capacity of _four_:
1213
1214```
1215Sending 0
1216Sending 1
1217Sending 2
1218Sending 3
1219Sending 4
1220```
1221
1222The first four elements are added to the buffer and the sender suspends when trying to send the fifth one.