Playing with Structured concurrency in Kotlin

Davide Cerbo
4 min readDec 16, 2019
Photo by Jeff Prieb from FreeImages

Studying about Kotlin Coroutine, I often read Structure concurrency but what it really means? Structured how many times do you hear this word about programming? Structured programming, is a programming paradigm born to improve code quality and clarity, by using structured control flow constructs of selection (if…then…elen) and repetition (while and for), block structures and subroutines. This concept born by some considerations made by Edsger W. Dijkstra in “Go To Statement Considered Harmful”.

Basically we have to stop to write:

10 i = 0
20 i = i + 10
30 PRINT "i: " + i
40 IF (i < 100) GOTO 20

In favor of:

int i = 0;
while(i < 100){
i = i + 10;
print("i: " + i);
}

Because rely on a row index makes our software very hard to maintain, while programming using block structures and subroutine is very helpful when we need to modify our code.

Why we cannot do the same when we have to do concurrency programming? Martin Sústrik, the ZeroMQ creator, introduce this concept for the first time in his blog, Roman Elizarov like his ideology and introduce this concept in Kotlin Coroutine two years later. Go back to our example…

Let’s imagine a simple game where the winner is who plays more times in 500 milliseconds:

fun main()  {
var playerOne = AtomicInteger();
var playerTwo = AtomicInteger();
thread {
println("Start match - ${Thread.currentThread().name}")
thread {
(1..10).forEach {
Thread.sleep(Random.nextLong(10, 200))
println("P1 $it - ${Thread.currentThread().name}")
playerOne.incrementAndGet()
}
}
thread {
(1..10).forEach {
Thread.sleep(Random.nextLong(10, 200))
println("P2 $it - ${Thread.currentThread().name}")
playerTwo.incrementAndGet()
}
}
Thread.sleep(500)
Thread.currentThread().interrupt();
println("End match! - ${Thread.currentThread().name}")
when {
playerOne.get() > playerTwo.get() -> println("P1 wins")
playerOne.get() < playerTwo.get() -> println("P2 wins")
playerOne.get() == playerTwo.get() -> println("Draw!")
}
}
println("end - ${Thread.currentThread().name}")
}

As you can see in the console above the player continue playing because the interruption of parent thread doesn’t stop the children execution. Of course, we can fix it, but this isn’t so easy and the code will not so clear to understand. Thanks to Kotlin syntax our code is structured, thread { … } seems a syntactic construct, but it isn’t actually structured concurrency because the lifetime of a thread isn’t bound to a code block. So, we are violating concepts behind structured programming.

So let’s go with a refactoring using coroutine:

fun main() = runBlocking {
var playerOne = AtomicInteger();
var playerTwo = AtomicInteger();
launch {
println("Start match - ${Thread.currentThread().name}")
launch {
(1..10).forEach {
delay(Random.nextLong(10, 200))
println("P1 $it - ${Thread.currentThread().name}")
playerOne.incrementAndGet()
}
}
launch {
(1..10).forEach {
delay(Random.nextLong(10, 200))
println("P2 $it - ${Thread.currentThread().name}")
playerTwo.incrementAndGet()
}
}
delay(500)
cancel()
println("End match! - ${Thread.currentThread().name}")
when {
playerOne.get() > playerTwo.get() -> println("P1 wins")
playerOne.get() < playerTwo.get() -> println("P2 wins")
playerOne.get() == playerTwo.get() -> println("Draw!")
}
}
println("end - ${Thread.currentThread().name}")
}

Now the players stop to play when the game ends!

So we reach our target about structured concurrency because using the launch syntactic construct the lifetime of a thread is bound to a code block and our code readability is awesome :)

This isn’t enough, another interesting feature of Structured concurrency is that the parent thread will complete only when all children complete.

fun main() = runBlocking {
launch {
println("Start - ${Thread.currentThread().name}")
launch {
(1..5).forEach {
delay(100)
println("A $it - ${Thread.currentThread().name} ")
}
}
launch {
(1..5).forEach {
delay(200)
println("B $it - ${Thread.currentThread().name} ")
}
}
}.invokeOnCompletion {
println("Complete! - ${Thread.currentThread().name}")
}
println("End main method - ${Thread.currentThread().name}")
}

In the example above the parent launch construct will print “Complete! — main” only after the completion of all children tasks.

We can do that in plain Java? Not yet, but Fiber is coming:

Do you wish to learn more? Visit this forum to find a lot of useful resources and discussion about Structured concurrency:

More on Kotlin Coroutine

Further reading

--

--