@@ -47,7 +47,7 @@ Run the following code:
47
47
import kotlinx.coroutines.*
48
48
49
49
fun main () {
50
- GlobalScope .launch { // launch new coroutine in background and continue
50
+ GlobalScope .launch { // launch a new coroutine in background and continue
51
51
delay(1000L ) // non-blocking delay for 1 second (default time unit is ms)
52
52
println (" World!" ) // print after delay
53
53
}
@@ -58,7 +58,7 @@ fun main() {
58
58
59
59
</div >
60
60
61
- > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-01.kt )
61
+ > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-01.kt ) .
62
62
63
63
You will see the following result:
64
64
@@ -98,7 +98,7 @@ Let's be explicit about blocking using [runBlocking] coroutine builder:
98
98
import kotlinx.coroutines.*
99
99
100
100
fun main () {
101
- GlobalScope .launch { // launch new coroutine in background and continue
101
+ GlobalScope .launch { // launch a new coroutine in background and continue
102
102
delay(1000L )
103
103
println (" World!" )
104
104
}
@@ -111,15 +111,15 @@ fun main() {
111
111
112
112
</div >
113
113
114
- > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-02.kt )
114
+ > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-02.kt ) .
115
115
116
116
<!-- - TEST
117
117
Hello,
118
118
World!
119
119
-->
120
120
121
121
The result is the same, but this code uses only non-blocking [ delay] .
122
- The main thread, that invokes ` runBlocking ` , _ blocks_ until the coroutine inside ` runBlocking ` completes.
122
+ The main thread invoking ` runBlocking ` _ blocks_ until the coroutine inside ` runBlocking ` completes.
123
123
124
124
This example can be also rewritten in a more idiomatic way, using ` runBlocking ` to wrap
125
125
the execution of the main function:
@@ -130,7 +130,7 @@ the execution of the main function:
130
130
import kotlinx.coroutines.*
131
131
132
132
fun main () = runBlocking<Unit > { // start main coroutine
133
- GlobalScope .launch { // launch new coroutine in background and continue
133
+ GlobalScope .launch { // launch a new coroutine in background and continue
134
134
delay(1000L )
135
135
println (" World!" )
136
136
}
@@ -141,7 +141,7 @@ fun main() = runBlocking<Unit> { // start main coroutine
141
141
142
142
</div >
143
143
144
- > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-02b.kt )
144
+ > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-02b.kt ) .
145
145
146
146
<!-- - TEST
147
147
Hello,
@@ -151,7 +151,7 @@ World!
151
151
Here ` runBlocking<Unit> { ... } ` works as an adaptor that is used to start the top-level main coroutine.
152
152
We explicitly specify its ` Unit ` return type, because a well-formed ` main ` function in Kotlin has to return ` Unit ` .
153
153
154
- This is also a way to write unit- tests for suspending functions:
154
+ This is also a way to write unit tests for suspending functions:
155
155
156
156
<!-- - INCLUDE
157
157
import kotlinx.coroutines.*
@@ -184,7 +184,7 @@ import kotlinx.coroutines.*
184
184
185
185
fun main () = runBlocking {
186
186
// sampleStart
187
- val job = GlobalScope .launch { // launch new coroutine and keep a reference to its Job
187
+ val job = GlobalScope .launch { // launch a new coroutine and keep a reference to its Job
188
188
delay(1000L )
189
189
println (" World!" )
190
190
}
@@ -196,7 +196,7 @@ fun main() = runBlocking {
196
196
197
197
</div >
198
198
199
- > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-03.kt )
199
+ > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-03.kt ) .
200
200
201
201
<!-- - TEST
202
202
Hello,
@@ -209,11 +209,11 @@ the background job in any way. Much better.
209
209
### Structured concurrency
210
210
211
211
There is still something to be desired for practical usage of coroutines.
212
- When we use ` GlobalScope.launch ` we create a top-level coroutine. Even though it is light-weight, it still
212
+ When we use ` GlobalScope.launch ` , we create a top-level coroutine. Even though it is light-weight, it still
213
213
consumes some memory resources while it runs. If we forget to keep a reference to the newly launched
214
214
coroutine it still runs. What if the code in the coroutine hangs (for example, we erroneously
215
215
delay for too long), what if we launched too many coroutines and ran out of memory?
216
- Having to manually keep a reference to all the launched coroutines and [ join] [ Job.join ] them is error-prone.
216
+ Having to manually keep references to all the launched coroutines and [ join] [ Job.join ] them is error-prone.
217
217
218
218
There is a better solution. We can use structured concurrency in our code.
219
219
Instead of launching coroutines in the [ GlobalScope] , just like we usually do with threads (threads are always global),
@@ -231,7 +231,7 @@ in its scope complete. Thus, we can make our example simpler:
231
231
import kotlinx.coroutines.*
232
232
233
233
fun main () = runBlocking { // this: CoroutineScope
234
- launch { // launch new coroutine in the scope of runBlocking
234
+ launch { // launch a new coroutine in the scope of runBlocking
235
235
delay(1000L )
236
236
println (" World!" )
237
237
}
@@ -241,7 +241,7 @@ fun main() = runBlocking { // this: CoroutineScope
241
241
242
242
</div >
243
243
244
- > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-03s.kt )
244
+ > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-03s.kt ) .
245
245
246
246
<!-- - TEST
247
247
Hello,
@@ -250,7 +250,7 @@ World!
250
250
251
251
### Scope builder
252
252
In addition to the coroutine scope provided by different builders, it is possible to declare your own scope using
253
- [ coroutineScope] builder. It creates new coroutine scope and does not complete until all launched children
253
+ [ coroutineScope] builder. It creates a coroutine scope and does not complete until all launched children
254
254
complete. The main difference between [ runBlocking] and [ coroutineScope] is that the latter does not block the current thread
255
255
while waiting for all children to complete.
256
256
@@ -265,23 +265,23 @@ fun main() = runBlocking { // this: CoroutineScope
265
265
println (" Task from runBlocking" )
266
266
}
267
267
268
- coroutineScope { // Creates a new coroutine scope
268
+ coroutineScope { // Creates a coroutine scope
269
269
launch {
270
270
delay(500L )
271
271
println (" Task from nested launch" )
272
272
}
273
273
274
274
delay(100L )
275
- println (" Task from coroutine scope" ) // This line will be printed before nested launch
275
+ println (" Task from coroutine scope" ) // This line will be printed before the nested launch
276
276
}
277
277
278
- println (" Coroutine scope is over" ) // This line is not printed until nested launch completes
278
+ println (" Coroutine scope is over" ) // This line is not printed until the nested launch completes
279
279
}
280
280
```
281
281
282
282
</div >
283
283
284
- > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-04.kt )
284
+ > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-04.kt ) .
285
285
286
286
<!-- - TEST
287
287
Task from coroutine scope
@@ -317,7 +317,7 @@ suspend fun doWorld() {
317
317
318
318
</div >
319
319
320
- > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-05.kt )
320
+ > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-05.kt ) .
321
321
322
322
<!-- - TEST
323
323
Hello,
@@ -328,10 +328,10 @@ World!
328
328
But what if the extracted function contains a coroutine builder which is invoked on the current scope?
329
329
In this case ` suspend ` modifier on the extracted function is not enough. Making ` doWorld ` extension
330
330
method on ` CoroutineScope ` is one of the solutions, but it may not always be applicable as it does not make API clearer.
331
- Idiomatic solution is to have either explicit ` CoroutineScope ` as a field in a class containing target function
332
- or implicit when outer class implements ` CoroutineScope ` .
331
+ The idiomatic solution is to have either an explicit ` CoroutineScope ` as a field in a class containing the target function
332
+ or an implicit one when the outer class implements ` CoroutineScope ` .
333
333
As a last resort, [ CoroutineScope(coroutineContext)] [ CoroutineScope() ] can be used, but such approach is structurally unsafe
334
- because you no longer have control on the scope this method is executed . Only private API can use this builder.
334
+ because you no longer have control on the scope of execution of this method . Only private APIs can use this builder.
335
335
336
336
### Coroutines ARE light-weight
337
337
@@ -354,7 +354,7 @@ fun main() = runBlocking {
354
354
355
355
</div >
356
356
357
- > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-06.kt )
357
+ > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-06.kt ) .
358
358
359
359
<!-- - TEST lines.size == 1 && lines[0] == ".".repeat(100_000) -->
360
360
@@ -386,7 +386,7 @@ fun main() = runBlocking {
386
386
387
387
</div >
388
388
389
- > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-07.kt )
389
+ > You can get full code [ here] ( ../kotlinx-coroutines-core/jvm/test/guide/example-basic-07.kt ) .
390
390
391
391
You can run and see that it prints three lines and terminates:
392
392
0 commit comments