@@ -749,16 +749,16 @@ to a specific thread, dispatch it to a thread pool, or let it run unconfined. Tr
749
749
fun main (args : Array <String >) = runBlocking<Unit > {
750
750
val jobs = arrayListOf<Job >()
751
751
jobs + = launch(Unconfined ) { // not confined -- will work with main thread
752
- println (" 'Unconfined': I'm working in thread ${Thread .currentThread().name} " )
752
+ println (" 'Unconfined': I'm working in thread ${Thread .currentThread().name} " )
753
753
}
754
- jobs + = launch(context ) { // context of the parent, runBlocking coroutine
755
- println (" 'context ': I'm working in thread ${Thread .currentThread().name} " )
754
+ jobs + = launch(coroutineContext ) { // context of the parent, runBlocking coroutine
755
+ println (" 'coroutineContext ': I'm working in thread ${Thread .currentThread().name} " )
756
756
}
757
757
jobs + = launch(CommonPool ) { // will get dispatched to ForkJoinPool.commonPool (or equivalent)
758
- println (" 'CommonPool': I'm working in thread ${Thread .currentThread().name} " )
758
+ println (" 'CommonPool': I'm working in thread ${Thread .currentThread().name} " )
759
759
}
760
760
jobs + = launch(newSingleThreadContext(" MyOwnThread" )) { // will get its own new thread
761
- println (" 'newSTC': I'm working in thread ${Thread .currentThread().name} " )
761
+ println (" 'newSTC': I'm working in thread ${Thread .currentThread().name} " )
762
762
}
763
763
jobs.forEach { it.join() }
764
764
}
@@ -769,15 +769,16 @@ fun main(args: Array<String>) = runBlocking<Unit> {
769
769
It produces the following output (maybe in different order):
770
770
771
771
``` text
772
- 'Unconfined': I'm working in thread main
773
- 'CommonPool': I'm working in thread ForkJoinPool.commonPool-worker-1
774
- 'newSTC': I'm working in thread MyOwnThread
775
- 'context ': I'm working in thread main
772
+ 'Unconfined': I'm working in thread main
773
+ 'CommonPool': I'm working in thread ForkJoinPool.commonPool-worker-1
774
+ 'newSTC': I'm working in thread MyOwnThread
775
+ 'coroutineContext ': I'm working in thread main
776
776
```
777
777
778
778
<!-- - TEST LINES_START_UNORDERED -->
779
779
780
- The difference between parent [ context] [ CoroutineScope.context ] and [ Unconfined] context will be shown later.
780
+ The difference between parent [ coroutineContext] [ CoroutineScope.coroutineContext ] and
781
+ [ Unconfined] context will be shown later.
781
782
782
783
### Unconfined vs confined dispatcher
783
784
@@ -786,7 +787,7 @@ first suspension point. After suspension it resumes in the thread that is fully
786
787
suspending function that was invoked. Unconfined dispatcher is appropriate when coroutine does not
787
788
consume CPU time nor updates any shared data (like UI) that is confined to a specific thread.
788
789
789
- On the other side, [ context ] [ CoroutineScope.context ] property that is available inside the block of any coroutine
790
+ On the other side, [ coroutineContext ] [ CoroutineScope.coroutineContext ] property that is available inside the block of any coroutine
790
791
via [ CoroutineScope] interface, is a reference to a context of this particular coroutine.
791
792
This way, a parent context can be inherited. The default context of [ runBlocking] , in particular,
792
793
is confined to be invoker thread, so inheriting it has the effect of confining execution to
@@ -796,14 +797,14 @@ this thread with a predictable FIFO scheduling.
796
797
fun main (args : Array <String >) = runBlocking<Unit > {
797
798
val jobs = arrayListOf<Job >()
798
799
jobs + = launch(Unconfined ) { // not confined -- will work with main thread
799
- println (" 'Unconfined': I'm working in thread ${Thread .currentThread().name} " )
800
+ println (" 'Unconfined': I'm working in thread ${Thread .currentThread().name} " )
800
801
delay(500 )
801
- println (" 'Unconfined': After delay in thread ${Thread .currentThread().name} " )
802
+ println (" 'Unconfined': After delay in thread ${Thread .currentThread().name} " )
802
803
}
803
- jobs + = launch(context ) { // context of the parent, runBlocking coroutine
804
- println (" 'context ': I'm working in thread ${Thread .currentThread().name} " )
804
+ jobs + = launch(coroutineContext ) { // context of the parent, runBlocking coroutine
805
+ println (" 'coroutineContext ': I'm working in thread ${Thread .currentThread().name} " )
805
806
delay(1000 )
806
- println (" 'context ': After delay in thread ${Thread .currentThread().name} " )
807
+ println (" 'coroutineContext ': After delay in thread ${Thread .currentThread().name} " )
807
808
}
808
809
jobs.forEach { it.join() }
809
810
}
@@ -814,16 +815,17 @@ fun main(args: Array<String>) = runBlocking<Unit> {
814
815
Produces the output:
815
816
816
817
``` text
817
- 'Unconfined': I'm working in thread main
818
- 'context ': I'm working in thread main
819
- 'Unconfined': After delay in thread kotlinx.coroutines.DefaultExecutor
820
- 'context ': After delay in thread main
818
+ 'Unconfined': I'm working in thread main
819
+ 'coroutineContext ': I'm working in thread main
820
+ 'Unconfined': After delay in thread kotlinx.coroutines.DefaultExecutor
821
+ 'coroutineContext ': After delay in thread main
821
822
```
822
823
823
824
<!-- - TEST LINES_START -->
824
825
825
- So, the coroutine that had inherited ` context ` of ` runBlocking {...} ` continues to execute in the ` main ` thread,
826
- while the unconfined one had resumed in the default executor thread that [ delay] function is using.
826
+ So, the coroutine that had inherited ` coroutineContext ` of ` runBlocking {...} ` continues to execute
827
+ in the ` main ` thread, while the unconfined one had resumed in the default executor thread that [ delay]
828
+ function is using.
827
829
828
830
### Debugging coroutines and threads
829
831
@@ -840,11 +842,11 @@ Run the following code with `-Dkotlinx.coroutines.debug` JVM option:
840
842
fun log (msg : String ) = println (" [${Thread .currentThread().name} ] $msg " )
841
843
842
844
fun main (args : Array <String >) = runBlocking<Unit > {
843
- val a = async(context ) {
845
+ val a = async(coroutineContext ) {
844
846
log(" I'm computing a piece of the answer" )
845
847
6
846
848
}
847
- val b = async(context ) {
849
+ val b = async(coroutineContext ) {
848
850
log(" I'm computing another piece of the answer" )
849
851
7
850
852
}
@@ -910,11 +912,11 @@ same coroutine as you can see in the output below:
910
912
### Job in the context
911
913
912
914
The coroutine [ Job] is part of its context. The coroutine can retrieve it from its own context
913
- using ` context [Job]` expression:
915
+ using ` coroutineContext [Job]` expression:
914
916
915
917
``` kotlin
916
918
fun main (args : Array <String >) = runBlocking<Unit > {
917
- println (" My job is ${context [Job ]} " )
919
+ println (" My job is ${coroutineContext [Job ]} " )
918
920
}
919
921
```
920
922
@@ -928,11 +930,12 @@ My job is BlockingCoroutine{Active}@65ae6ba4
928
930
929
931
<!-- - TEST lines.size == 1 && lines[0].startsWith("My job is BlockingCoroutine{Active}@") -->
930
932
931
- So, [ isActive] [ CoroutineScope.isActive ] in [ CoroutineScope] is just a convenient shortcut for ` context[Job]!!.isActive ` .
933
+ So, [ isActive] [ CoroutineScope.isActive ] in [ CoroutineScope] is just a convenient shortcut for
934
+ ` coroutineContext[Job]!!.isActive ` .
932
935
933
936
### Children of a coroutine
934
937
935
- When [ context ] [ CoroutineScope.context ] of a coroutine is used to launch another coroutine,
938
+ When [ coroutineContext ] [ CoroutineScope.coroutineContext ] of a coroutine is used to launch another coroutine,
936
939
the [ Job] of the new coroutine becomes
937
940
a _ child_ of the parent coroutine's job. When the parent coroutine is cancelled, all its children
938
941
are recursively cancelled, too.
@@ -948,7 +951,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
948
951
println (" job1: I am not affected by cancellation of the request" )
949
952
}
950
953
// and the other inherits the parent context
951
- val job2 = launch(context ) {
954
+ val job2 = launch(coroutineContext ) {
952
955
println (" job2: I am a child of the request coroutine" )
953
956
delay(1000 )
954
957
println (" job2: I will not execute this line if my parent request is cancelled" )
@@ -986,9 +989,9 @@ its dispatcher replaced:
986
989
``` kotlin
987
990
fun main (args : Array <String >) = runBlocking<Unit > {
988
991
// start a coroutine to process some kind of incoming request
989
- val request = launch(context ) { // use the context of `runBlocking`
992
+ val request = launch(coroutineContext ) { // use the context of `runBlocking`
990
993
// spawns CPU-intensive child job in CommonPool !!!
991
- val job = launch(context + CommonPool ) {
994
+ val job = launch(coroutineContext + CommonPool ) {
992
995
println (" job: I am a child of the request coroutine, but with a different dispatcher" )
993
996
delay(1000 )
994
997
println (" job: I will not execute this line if my parent request is cancelled" )
@@ -1075,7 +1078,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
1075
1078
// now launch ten coroutines for a demo, each working for a different time
1076
1079
val coroutines = List (10 ) { i ->
1077
1080
// they are all children of our job object
1078
- launch(context + job) { // we use the context of main runBlocking thread, but with our own job object
1081
+ launch(coroutineContext + job) { // we use the context of main runBlocking thread, but with our own job object
1079
1082
delay(i * 200L ) // variable delay 0ms, 200ms, 400ms, ... etc
1080
1083
println (" Coroutine $i is done" )
1081
1084
}
@@ -1305,11 +1308,11 @@ running the whole pipeline in the context of the main thread:
1305
1308
1306
1309
``` kotlin
1307
1310
fun main (args : Array <String >) = runBlocking<Unit > {
1308
- var cur = numbersFrom(context , 2 )
1311
+ var cur = numbersFrom(coroutineContext , 2 )
1309
1312
for (i in 1 .. 10 ) {
1310
1313
val prime = cur.receive()
1311
1314
println (prime)
1312
- cur = filter(context , cur, prime)
1315
+ cur = filter(coroutineContext , cur, prime)
1313
1316
}
1314
1317
}
1315
1318
```
@@ -1426,8 +1429,8 @@ Now, let us see what happens if we launch a couple of coroutines sending strings
1426
1429
``` kotlin
1427
1430
fun main (args : Array <String >) = runBlocking<Unit > {
1428
1431
val channel = Channel <String >()
1429
- launch(context ) { sendString(channel, " foo" , 200L ) }
1430
- launch(context ) { sendString(channel, " BAR!" , 500L ) }
1432
+ launch(coroutineContext ) { sendString(channel, " foo" , 200L ) }
1433
+ launch(coroutineContext ) { sendString(channel, " BAR!" , 500L ) }
1431
1434
repeat(6 ) { // receive first six
1432
1435
println (channel.receive())
1433
1436
}
@@ -1464,7 +1467,7 @@ Take a look at the behavior of the following code:
1464
1467
``` kotlin
1465
1468
fun main (args : Array <String >) = runBlocking<Unit > {
1466
1469
val channel = Channel <Int >(4 ) // create buffered channel
1467
- launch(context ) { // launch sender coroutine
1470
+ launch(coroutineContext ) { // launch sender coroutine
1468
1471
repeat(10 ) {
1469
1472
println (" Sending $it " ) // print before sending each element
1470
1473
channel.send(it) // will suspend when buffer is full
@@ -1504,8 +1507,8 @@ data class Ball(var hits: Int)
1504
1507
1505
1508
fun main (args : Array <String >) = runBlocking<Unit > {
1506
1509
val table = Channel <Ball >() // a shared table
1507
- launch(context ) { player(" ping" , table) }
1508
- launch(context ) { player(" pong" , table) }
1510
+ launch(coroutineContext ) { player(" ping" , table) }
1511
+ launch(coroutineContext ) { player(" pong" , table) }
1509
1512
table.send(Ball (0 )) // serve the ball
1510
1513
delay(1000 ) // delay 1 second
1511
1514
table.receive() // game over, grab the ball
@@ -1893,8 +1896,8 @@ Let us run it all seven times:
1893
1896
1894
1897
``` kotlin
1895
1898
fun main (args : Array <String >) = runBlocking<Unit > {
1896
- val fizz = fizz(context )
1897
- val buzz = buzz(context )
1899
+ val fizz = fizz(coroutineContext )
1900
+ val buzz = buzz(coroutineContext )
1898
1901
repeat(7 ) {
1899
1902
selectFizzBuzz(fizz, buzz)
1900
1903
}
@@ -1948,10 +1951,10 @@ channel `b` that produces "World" four times:
1948
1951
``` kotlin
1949
1952
fun main (args : Array <String >) = runBlocking<Unit > {
1950
1953
// we are using the context of the main thread in this example for predictability ...
1951
- val a = produce<String >(context ) {
1954
+ val a = produce<String >(coroutineContext ) {
1952
1955
repeat(4 ) { send(" Hello $it " ) }
1953
1956
}
1954
- val b = produce<String >(context ) {
1957
+ val b = produce<String >(coroutineContext ) {
1955
1958
repeat(4 ) { send(" World $it " ) }
1956
1959
}
1957
1960
repeat(8 ) { // print first eight results
@@ -2012,7 +2015,7 @@ Consumer is going to be quite slow, taking 250 ms to process each number:
2012
2015
``` kotlin
2013
2016
fun main (args : Array <String >) = runBlocking<Unit > {
2014
2017
val side = Channel <Int >() // allocate side channel
2015
- launch(context ) { // this is a very fast consumer for the side channel
2018
+ launch(coroutineContext ) { // this is a very fast consumer for the side channel
2016
2019
side.consumeEach { println (" Side channel has $it " ) }
2017
2020
}
2018
2021
produceNumbers(side).consumeEach {
@@ -2145,7 +2148,7 @@ data to it:
2145
2148
``` kotlin
2146
2149
fun main (args : Array <String >) = runBlocking<Unit > {
2147
2150
val chan = Channel <Deferred <String >>() // the channel for test
2148
- launch(context ) { // launch printing coroutine
2151
+ launch(coroutineContext ) { // launch printing coroutine
2149
2152
for (s in switchMapDeferreds(chan))
2150
2153
println (s) // print each received string
2151
2154
}
@@ -2202,7 +2205,7 @@ Channel was closed
2202
2205
[ Job.start ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-job/start.html
2203
2206
[ CommonPool ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-common-pool/index.html
2204
2207
[ CoroutineDispatcher ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-dispatcher/index.html
2205
- [ CoroutineScope.context ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-scope/context.html
2208
+ [ CoroutineScope.coroutineContext ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-scope/coroutine- context.html
2206
2209
[ Unconfined ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-unconfined/index.html
2207
2210
[ newCoroutineContext ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/new-coroutine-context.html
2208
2211
[ CoroutineName ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-name/index.html
0 commit comments