@@ -76,6 +76,7 @@ This is a short guide on core features of `kotlinx.coroutines` with a series of
76
76
* [ Fan-out] ( #fan-out )
77
77
* [ Fan-in] ( #fan-in )
78
78
* [ Buffered channels] ( #buffered-channels )
79
+ * [ Channels are fair] ( #channels-are-fair )
79
80
* [ Shared mutable state and concurrency] ( #shared-mutable-state-and-concurrency )
80
81
* [ The problem] ( #the-problem )
81
82
* [ Volatiles are of no help] ( #volatiles-are-of-no-help )
@@ -1477,6 +1478,53 @@ Sending 4
1477
1478
1478
1479
The first four elements are added to the buffer and the sender suspends when trying to send the fifth one.
1479
1480
1481
+
1482
+ ### Channels are fair
1483
+
1484
+ Send and receive operations to channels are _ fair_ with respect to the order of their invocation from
1485
+ multiple coroutines. They are served in first-in first-out order, e.g. the first coroutine to invoke ` receive `
1486
+ gets the element. In the following example two coroutines "ping" and "pong" are
1487
+ receiving the "ball" object from the shared "table" channel.
1488
+
1489
+ ``` kotlin
1490
+ data class Ball (var hits : Int )
1491
+
1492
+ fun main (args : Array <String >) = runBlocking<Unit > {
1493
+ val table = Channel <Ball >() // a shared table
1494
+ launch(context) { player(" ping" , table) }
1495
+ launch(context) { player(" pong" , table) }
1496
+ table.send(Ball (0 )) // serve the ball
1497
+ delay(1000 ) // delay 1 second
1498
+ table.receive() // game over, grab the ball
1499
+ }
1500
+
1501
+ suspend fun player (name : String , table : Channel <Ball >) {
1502
+ for (ball in table) { // receive the ball in a loop
1503
+ ball.hits++
1504
+ println (" $name $ball " )
1505
+ delay(200 ) // wait a bit
1506
+ table.send(ball) // send the ball back
1507
+ }
1508
+ }
1509
+ ```
1510
+
1511
+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-channel-09.kt )
1512
+
1513
+ The "ping" coroutine is started first, so it is the first one to receive the ball. Even though "ping"
1514
+ coroutine immediately starts receiving the ball again after sending it back to the table, the ball gets
1515
+ received by the "pong" coroutine, because it was already waiting for it:
1516
+
1517
+ ``` text
1518
+ ping Ball(hits=1)
1519
+ pong Ball(hits=2)
1520
+ ping Ball(hits=3)
1521
+ pong Ball(hits=4)
1522
+ ping Ball(hits=5)
1523
+ pong Ball(hits=6)
1524
+ ```
1525
+
1526
+ <!-- - TEST -->
1527
+
1480
1528
## Shared mutable state and concurrency
1481
1529
1482
1530
Coroutines can be executed concurrently using a multi-threaded dispatcher like [ CommonPool] . It presents
0 commit comments