@@ -76,6 +76,7 @@ This is a short guide on core features of `kotlinx.coroutines` with a series of
7676 * [ Fan-out] ( #fan-out )
7777 * [ Fan-in] ( #fan-in )
7878 * [ Buffered channels] ( #buffered-channels )
79+ * [ Channels are fair] ( #channels-are-fair )
7980* [ Shared mutable state and concurrency] ( #shared-mutable-state-and-concurrency )
8081 * [ The problem] ( #the-problem )
8182 * [ Volatiles are of no help] ( #volatiles-are-of-no-help )
@@ -1477,6 +1478,53 @@ Sending 4
14771478
14781479The first four elements are added to the buffer and the sender suspends when trying to send the fifth one.
14791480
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+
14801528## Shared mutable state and concurrency
14811529
14821530Coroutines can be executed concurrently using a multi-threaded dispatcher like [ CommonPool] . It presents
0 commit comments