Skip to content

Commit a4d45d2

Browse files
committed
A more gradual introduction to runBlocking and coroutines.
Fixes #166
1 parent 7da4243 commit a4d45d2

File tree

5 files changed

+82
-19
lines changed

5 files changed

+82
-19
lines changed

core/kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-01.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ package guide.basic.example01
2020
import kotlinx.coroutines.experimental.*
2121

2222
fun main(args: Array<String>) {
23-
launch { // launch new coroutine
23+
launch { // launch new coroutine in background and continue
2424
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
2525
println("World!") // print after delay
2626
}
27-
println("Hello,") // main function continues while coroutine is delayed
27+
println("Hello,") // main thread continues while coroutine is delayed
2828
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
2929
}

core/kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-02.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ package guide.basic.example02
1919

2020
import kotlinx.coroutines.experimental.*
2121

22-
fun main(args: Array<String>) = runBlocking<Unit> { // start main coroutine
23-
launch { // launch new coroutine
22+
fun main(args: Array<String>) {
23+
launch { // launch new coroutine in background and continue
2424
delay(1000L)
2525
println("World!")
2626
}
27-
println("Hello,") // main coroutine continues while child is delayed
28-
delay(2000L) // non-blocking delay for 2 seconds to keep JVM alive
27+
println("Hello,") // main thread continues here immediately
28+
runBlocking { // but this expression blocks the main thread
29+
delay(2000L) // ... while we delay for 2 seconds to keep JVM alive
30+
}
2931
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2016-2017 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
18+
package guide.basic.example02b
19+
20+
import kotlinx.coroutines.experimental.*
21+
22+
fun main(args: Array<String>) = runBlocking<Unit> { // start main coroutine
23+
launch { // launch new coroutine in background and continue
24+
delay(1000L)
25+
println("World!")
26+
}
27+
println("Hello,") // main coroutine continues here immediately
28+
delay(2000L) // delaying for 2 seconds to keep JVM alive
29+
}

core/kotlinx-coroutines-core/src/test/kotlin/guide/test/GuideTest.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ class GuideTest {
2121
)
2222
}
2323

24+
@Test
25+
fun testGuideBasicExample02b() {
26+
test("GuideBasicExample02b") { guide.basic.example02b.main(emptyArray()) }.verifyLines(
27+
"Hello,",
28+
"World!"
29+
)
30+
}
31+
2432
@Test
2533
fun testGuideBasicExample03() {
2634
test("GuideBasicExample03") { guide.basic.example03.main(emptyArray()) }.verifyLines(

coroutines-guide.md

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class GuideTest {
3232

3333
# Guide to kotlinx.coroutines by example
3434

35-
This is a short guide on core features of `kotlinx.coroutines` with a series of examples.
35+
This is a guide on core features of `kotlinx.coroutines` with a series of examples.
3636

3737
## Introduction and setup
3838

@@ -41,7 +41,7 @@ libraries to utilize coroutines. Unlike many other languages with similar capabi
4141
are not keywords in Kotlin and are not even part of its standard library.
4242

4343
`kotlinx.coroutines` is one such rich library. It contains a number of high-level
44-
coroutine-enabled primitives that this guide covers, including `async` and `await`.
44+
coroutine-enabled primitives that this guide covers, including `launch`, `async` and others.
4545
You need to add a dependency on `kotlinx-coroutines-core` module as explained
4646
[here](README.md#using-in-your-projects) to use primitives from this guide in your projects.
4747

@@ -117,11 +117,11 @@ Run the following code:
117117

118118
```kotlin
119119
fun main(args: Array<String>) {
120-
launch { // launch new coroutine
120+
launch { // launch new coroutine in background and continue
121121
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
122122
println("World!") // print after delay
123123
}
124-
println("Hello,") // main function continues while coroutine is delayed
124+
println("Hello,") // main thread continues while coroutine is delayed
125125
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
126126
}
127127
```
@@ -153,18 +153,20 @@ coroutine and it can be only used from a coroutine.
153153

154154
### Bridging blocking and non-blocking worlds
155155

156-
The first example mixes _non-blocking_ `delay(...)` and _blocking_ `Thread.sleep(...)` in the same
157-
code of `main` function. It is easy to get lost. Let's cleanly separate blocking and non-blocking
158-
worlds by using [runBlocking]:
156+
The first example mixes _non-blocking_ `delay(...)` and _blocking_ `Thread.sleep(...)` in the same code.
157+
It is easy to get lost which one is blocking and which one is not.
158+
Let's be explicit about blocking using [runBlocking] coroutine builder:
159159

160160
```kotlin
161-
fun main(args: Array<String>) = runBlocking<Unit> { // start main coroutine
162-
launch { // launch new coroutine
161+
fun main(args: Array<String>) {
162+
launch { // launch new coroutine in background and continue
163163
delay(1000L)
164164
println("World!")
165165
}
166-
println("Hello,") // main coroutine continues while child is delayed
167-
delay(2000L) // non-blocking delay for 2 seconds to keep JVM alive
166+
println("Hello,") // main thread continues here immediately
167+
runBlocking { // but this expression blocks the main thread
168+
delay(2000L) // ... while we delay for 2 seconds to keep JVM alive
169+
}
168170
}
169171
```
170172

@@ -176,9 +178,31 @@ World!
176178
-->
177179

178180
The result is the same, but this code uses only non-blocking [delay].
181+
The the main thread, that invokes `runBlocking`, _blocks_ until the coroutine inside `runBlocking` is active.
182+
183+
This example can be also rewritten in a more idiomatic way, using `runBlocking` to wrap
184+
the execution of the main function:
185+
186+
```kotlin
187+
fun main(args: Array<String>) = runBlocking<Unit> { // start main coroutine
188+
launch { // launch new coroutine in background and continue
189+
delay(1000L)
190+
println("World!")
191+
}
192+
println("Hello,") // main coroutine continues here immediately
193+
delay(2000L) // delaying for 2 seconds to keep JVM alive
194+
}
195+
```
196+
197+
> You can get full code [here](core/kotlinx-coroutines-core/src/test/kotlin/guide/example-basic-02b.kt)
198+
199+
<!--- TEST
200+
Hello,
201+
World!
202+
-->
179203

180-
`runBlocking { ... }` works as an adaptor that is used here to start the top-level main coroutine.
181-
The regular code outside of `runBlocking` _blocks_, until the coroutine inside `runBlocking` is active.
204+
Here `runBlocking<Unit> { ... }` works as an adaptor that is used to start the top-level main coroutine.
205+
We explicitly specify its `Unit` return type, because a well-formed `main` function in Kotlin has to return `Unit`.
182206

183207
This is also a way to write unit-tests for suspending functions:
184208

0 commit comments

Comments
 (0)