@@ -4,6 +4,8 @@ This is a short guide on core features of `kotlinx.coroutines` with a series of
4
4
5
5
## Table of contents
6
6
7
+ <!-- - TOC -->
8
+
7
9
* [ Coroutine basics] ( #coroutine-basics )
8
10
* [ Your first coroutine] ( #your-first-coroutine )
9
11
* [ Bridging blocking and non-blocking worlds] ( #bridging-blocking-and-non-blocking-worlds )
@@ -23,20 +25,20 @@ This is a short guide on core features of `kotlinx.coroutines` with a series of
23
25
* [ Concurrent using deferred value] ( #concurrent-using-deferred-value )
24
26
* [ Lazily deferred value] ( #lazily-deferred-value )
25
27
* [ Coroutine context and dispatchers] ( #coroutine-context-and-dispatchers )
26
- * [ Dispatchers and threads] ( #Dispatchers -and-threads )
28
+ * [ Dispatchers and threads] ( #dispatchers -and-threads )
27
29
* [ Unconfined vs confined dispatcher] ( #unconfined-vs-confined-dispatcher )
28
30
* [ Debugging coroutines and threads] ( #debugging-coroutines-and-threads )
29
31
* [ Jumping between threads] ( #jumping-between-threads )
30
32
* [ Job in the context] ( #job-in-the-context )
31
33
* [ Children of a coroutine] ( #children-of-a-coroutine )
32
34
* [ Combining contexts] ( #combining-contexts )
33
35
* [ Naming coroutines for debugging] ( #naming-coroutines-for-debugging )
34
-
36
+
35
37
<!-- - KNIT kotlinx-coroutines-core/src/test/kotlin/guide/.*\.kt -->
36
38
37
- <!-- - INCLUDE .*/example-([0-9]+)\.kt
39
+ <!-- - INCLUDE .*/example-([a-z]+)-([ 0-9]+)\.kt
38
40
// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
39
- package guide.example $$1
41
+ package guide.$$1.example$$2
40
42
41
43
import kotlinx.coroutines.experimental.*
42
44
-->
@@ -60,7 +62,7 @@ fun main(args: Array<String>) {
60
62
}
61
63
```
62
64
63
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-11 .kt )
65
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-01 .kt )
64
66
65
67
Run this code:
66
68
@@ -98,7 +100,7 @@ fun main(args: Array<String>) = runBlocking<Unit> { // start main coroutine
98
100
}
99
101
```
100
102
101
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-12 .kt )
103
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-02 .kt )
102
104
103
105
The result is the same, but this code uses only non-blocking ` delay ` .
104
106
@@ -134,7 +136,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
134
136
}
135
137
```
136
138
137
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-13 .kt )
139
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-03 .kt )
138
140
139
141
Now the result is still the same, but the code of the main coroutine is not tied to the duration of
140
142
the background job in any way. Much better.
@@ -161,7 +163,7 @@ suspend fun doWorld() {
161
163
}
162
164
```
163
165
164
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-14 .kt )
166
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-04 .kt )
165
167
166
168
### Coroutines ARE light-weight
167
169
@@ -179,7 +181,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
179
181
}
180
182
```
181
183
182
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-15 .kt )
184
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-05 .kt )
183
185
184
186
It starts 100K coroutines and, after a second, each coroutine prints a dot.
185
187
Now, try that with threads. What would happen? (Most likely your code will produce some sort of out-of-memory error)
@@ -201,7 +203,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
201
203
}
202
204
```
203
205
204
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-16 .kt )
206
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-06 .kt )
205
207
206
208
You can run and see that it prints three lines and terminates:
207
209
@@ -239,7 +241,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
239
241
}
240
242
```
241
243
242
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-21 .kt )
244
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-01 .kt )
243
245
244
246
It produces the following output:
245
247
@@ -282,7 +284,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
282
284
}
283
285
```
284
286
285
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-22 .kt )
287
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-02 .kt )
286
288
287
289
Run it to see that it continues to print "I'm sleeping" even after cancellation.
288
290
@@ -315,7 +317,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
315
317
}
316
318
```
317
319
318
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-23 .kt )
320
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-03 .kt )
319
321
320
322
As you can see, now this loop can be cancelled. ` isActive ` is a property that is available inside
321
323
the code of coroutines via ` CoroutineScope ` object.
@@ -346,7 +348,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
346
348
}
347
349
```
348
350
349
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-24 .kt )
351
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-04 .kt )
350
352
351
353
The example above produces the following output:
352
354
@@ -392,7 +394,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
392
394
}
393
395
```
394
396
395
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-25 .kt )
397
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-05 .kt )
396
398
397
399
### Timeout
398
400
@@ -413,7 +415,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
413
415
}
414
416
```
415
417
416
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-26 .kt )
418
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-cancel-06 .kt )
417
419
418
420
It produces the following output:
419
421
@@ -442,6 +444,10 @@ Assume that we have two suspending functions defined elsewhere that do something
442
444
remote service call or computation. We'll just pretend they are useful, but each one will just actaully
443
445
delay for a second for the purpose of this example:
444
446
447
+ <!-- - INCLUDE .*/example-compose-([0-9]+).kt
448
+ import kotlin.system.measureTimeMillis
449
+ -->
450
+
445
451
``` kotlin
446
452
suspend fun doSomethingUsefulOne (): Int {
447
453
delay(1000L ) // pretend we are doing something useful here
@@ -454,6 +460,8 @@ suspend fun doSomethingUsefulTwo(): Int {
454
460
}
455
461
```
456
462
463
+ <!-- - INCLUDE .*/example-compose-([0-9]+).kt -->
464
+
457
465
What do we do if need to invoke them _ sequentially_ -- first ` doSomethingUsefulOne ` _ and then_
458
466
` doSomethingUsefulTwo ` and compute the sum of their results?
459
467
In practise we do this if we use the results of the first function to make a decision on whether we need
@@ -463,10 +471,6 @@ We just use a normal sequential invocation, because the code in the coroutine, j
463
471
code, is _ sequential_ by default. The following example demonstrates that by measuring the total
464
472
time it takes to execute both suspending functions:
465
473
466
- <!-- - INCLUDE .*/example-3[1-9].kt
467
- import kotlin.system.measureTimeMillis
468
- -->
469
-
470
474
``` kotlin
471
475
fun main (args : Array <String >) = runBlocking<Unit > {
472
476
val time = measureTimeMillis {
@@ -478,7 +482,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
478
482
}
479
483
```
480
484
481
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-31 .kt )
485
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-01 .kt )
482
486
483
487
It produces something like this:
484
488
@@ -498,19 +502,6 @@ does not carry any resulting value, while `defer` returns a `Deferred` -- a kind
498
502
that represent a promise to provide result later. You can use ` .await() ` on a deferred value to get its eventual result,
499
503
but ` Deferred ` is also a ` Job ` , so you can cancel it if needed.
500
504
501
- <!-- - INCLUDE .*/example-3[2-9].kt
502
-
503
- suspend fun doSomethingUsefulOne(): Int {
504
- delay(1000L) // pretend we are doing something useful here
505
- return 13
506
- }
507
-
508
- suspend fun doSomethingUsefulTwo(): Int {
509
- delay(1000L) // pretend we are doing something useful here, too
510
- return 29
511
- }
512
- -->
513
-
514
505
``` kotlin
515
506
fun main (args : Array <String >) = runBlocking<Unit > {
516
507
val time = measureTimeMillis {
@@ -522,7 +513,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
522
513
}
523
514
```
524
515
525
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-32 .kt )
516
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-02 .kt )
526
517
527
518
It produces something like this:
528
519
@@ -551,7 +542,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
551
542
}
552
543
```
553
544
554
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-33 .kt )
545
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-compose-03 .kt )
555
546
556
547
It produces something like this:
557
548
@@ -595,7 +586,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
595
586
}
596
587
```
597
588
598
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-41 .kt )
589
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-context-01 .kt )
599
590
600
591
It produces the following output (maybe in different order):
601
592
@@ -638,7 +629,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
638
629
}
639
630
```
640
631
641
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-42 .kt )
632
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-contest-02 .kt )
642
633
643
634
Produces the output:
644
635
@@ -679,7 +670,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
679
670
}
680
671
```
681
672
682
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-43 .kt )
673
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-context-03 .kt )
683
674
684
675
There are three coroutines. The main couroutine (#1 ) -- ` runBlocking ` one,
685
676
and two coroutines computing deferred values ` a ` (#2 ) and ` b ` (#3 ).
@@ -718,7 +709,7 @@ fun main(args: Array<String>) {
718
709
}
719
710
```
720
711
721
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-44 .kt )
712
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-context-04 .kt )
722
713
723
714
It demonstrates two new techniques. One is using ` runBlocking ` with an explicitly specified context, and
724
715
the second one is using ` run(context) {...} ` to change a context of a coroutine while still staying in the
@@ -741,7 +732,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
741
732
}
742
733
```
743
734
744
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-45 .kt )
735
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-context-05 .kt )
745
736
746
737
It produces
747
738
@@ -784,7 +775,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
784
775
}
785
776
```
786
777
787
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-46 .kt )
778
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-context-06 .kt )
788
779
789
780
The output of this code is:
790
781
@@ -820,7 +811,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
820
811
}
821
812
```
822
813
823
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-47 .kt )
814
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-context-07 .kt )
824
815
825
816
The expected outcome of this code is:
826
817
@@ -859,7 +850,7 @@ fun main(args: Array<String>) = runBlocking(CoroutineName("main")) {
859
850
}
860
851
```
861
852
862
- > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-48 .kt )
853
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-context-08 .kt )
863
854
864
855
The output it produces with ` -Dkotlinx.coroutines.debug ` JVM option is similar to:
865
856
0 commit comments