Skip to content

Commit bb1cf1e

Browse files
committed
Clarify parallelism execution of asynchronous computations
1 parent f523c9a commit bb1cf1e

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

_overviews/scala3-book/concurrency.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,17 +182,18 @@ See the [Futures and Promises][futures] page for a discussion of additional meth
182182
## Running multiple futures and joining their results
183183

184184
To run multiple computations in parallel and join their results when all of the futures have been completed, use a `for` expression.
185+
185186
The correct approach is:
186187

187-
1. Create the futures
188+
1. Run the computations that return `Future` results
188189
2. Merge their results in a `for` expression
189190
3. Extract the merged result using `onComplete` or a similar technique
190191

191192

192193
### An example
193194

194195
The three steps of the correct approach are shown in the following example.
195-
A key is that you first create the futures and then join them in the `for` expression:
196+
A key is that you first run the computations that return futures, and then join them in the `for` expression:
196197

197198
```scala
198199
import scala.concurrent.Future
@@ -207,12 +208,12 @@ def sleep(millis: Long) = Thread.sleep(millis)
207208

208209
println(s"creating the futures: ${delta()}")
209210

210-
// (1) create the futures
211+
// (1) run the computations that return futures
211212
val f1 = Future { sleep(800); 1 } // eventually returns 1
212213
val f2 = Future { sleep(200); 2 } // eventually returns 2
213214
val f3 = Future { sleep(400); 3 } // eventually returns 3
214215

215-
// (2) run them simultaneously in a `for` expression
216+
// (2) join them in a `for` expression
216217
val result =
217218
for
218219
r1 <- f1
@@ -252,10 +253,23 @@ All of that code is run on the JVM’s main thread.
252253
Then, at 806 ms, the three futures complete and the code in the `yield` block is run.
253254
Then the code immediately goes to the `Success` case in the `onComplete` method.
254255

255-
The 806 ms output is a key to seeing that the three futures are run in parallel.
256-
If they were run sequentially, the total time would be about 1,400 ms---the sum of the sleep times of the three futures.
257-
But because they’re run in parallel, the total time is just slightly longer than the longest-running future: `f1`, which is 800 ms.
258-
256+
The 806 ms output is a key to seeing that the three computations are run in parallel.
257+
If they were run sequentially, the total time would be about 1,400 ms---the sum of the sleep times of the three computations.
258+
But because they’re run in parallel, the total time is just slightly longer than the longest-running computation: `f1`, which is 800 ms.
259+
260+
> Notice that if the computations were run within the `for` expression, they
261+
> would be executed sequentially, not in parallel:
262+
> ~~~
263+
> // Sequential execution (no parallelism!)
264+
> for
265+
> r1 <- Future { sleep(800); 1 }
266+
> r2 <- Future { sleep(200); 2 }
267+
> r3 <- Future { sleep(400); 3 }
268+
> yield
269+
> r1 + r2 + r3
270+
> ~~~
271+
> So, if you want the computations to be possibly run in parallel, remember
272+
> to run them outside of the `for` expression.
259273
260274
### A method that returns a future
261275

0 commit comments

Comments
 (0)