Concurrency Primitives in Kotlin

I've recently started reading "Android Concurrency" by G. Blake Meike, and so far I can highly recommend this great book: it contains quite a lot of insight into how various Android concurrency mechanisms work, when to prefer one approach over the other and how to get the best of the tools at your disposal. I decided to follow along with the code examples and recreate them on my computer, and since I'm deeply in love with Kotlin, I thought it would be a great idea to translate the examples into Kotlin on the go. In one of the first chapters the author revisits concurrency basics in Java, and when I started rewriting the code examples in Kotlin, I was quite surprised to find out that:

There's no synchronized keyword in Kotlin

There's no volatile keyword in Kotlin

Kotlin's Any, which is analogous to Java's Object, doesn't have wait(), notify() and notifyAll() methods

So how does concurrency work in Kotlin? This question has been asked on the Kotlin forum and here's the answer from Andrey Breslav, Kotlin Project Lead:

Kotlin deliberately has no constructs for concurrency built into the language. We believe this should be handled by libraries.

Although Kotlin doesn't have these things built into the language, it still provides quite a bunch of low-level concurrency tools. Let's take a look at what's in store.

Creating Threads

There are two ways to create a thread in Java: extending the Thread class, or instantiating it and passing a Runnable through the constructor. Since you can easily use Java classes in Kotlin, both solutions work just fine. Here's how you'd subclass Thread:

The annotation has the same effect as Java's synchronized: it'll mark the JVM method as synchronized. For synchronized blocks you'll have to use the synchronized() function, which takes a lock as the parameter:

The behavior is similar to @Synchronized: @Volatile will mark the JVM backing field as volatile.

wait(), notify() and notifyAll()

Every class in Kotlin inherits from Any, but Any doesn't declare wait(), notify() and notifyAll(), meaning that these methods can't be called on a Kotlin class. But you still can use an instance of java.lang.Object as a lock and call the methods on it. Here's a solution to the Producer/Consumer problem that uses Object as the lock:

Does it look hacky? Well, it is. Truth is that if you're relying on such low-level constructs in your code - most likely you're doing something wrong. Nowadays there's a ton of high-level concurrency mechanisms for every purpose in both Java and Kotlin. Here's a great Stackoverflow answer that provides a list of tools available for writing concurrent code in Kotlin.

Conclusion

Although they're not used frequently, it's still important to know and understand the basic concurrency tools. Turns out those work a bit differently in Kotlin than in Java, but all major mechanisms are supported. And remember that Kotlin interacts really well with Java, so you can just rely on Java classes if the Kotlin counterparts are missing. Have fun!

If you've enjoyed this short article, please share it with your network using one of the buttons below. Thanks, and have a Merry Christmas!