Kotlin for Lunch - Atomic<T>

Christoph Frei
The Startup
Published in
2 min readSep 16, 2020

“Kotlin for Lunch” collects Kotlin exercises, usage patterns, or “the Kotlin way” to solve development issues. This article should be short enough to have fun with Kotlin during a short lunch break.

We are here today: Kotlin > Coroutines > Concurrency

Kotlins Mutex is a nice idea when you need to lock a code block from beeing executed at the same time, but the code examples show them almost always together with a variable:

Mutex example (shortened) from the official Kotlin docs.

So why not have a builtin variable that can only be modified when the Mutex is locked? If you look at the Kotlin docs, you find AtomicInt, AtomicLong, and a few others — but not for all platforms (“native” only), and nowhere a generic Atomic<T>. Its time to change that.

So lets introduce Atomic<T>, an object that allows you to modify the value of type T, when no one else can. Even better, lets inherit from Mutex, so every Atomic<T> becomes also a Mutex and you get the Mutex functions for free.

Mutex() is an extension function and provides a Mutex object that implements that interface. By delegating the implementation to this object, we save all the function forwarding and get a very slim class definition. All functions and properties from Mutex are available without any boilerplate.

Lets try it out with some code:

Works nice. But wait a second, having to call a variable inside a lambda that was called from that very same variable doesn’t look good, or as others say, it smells.

It would be much more cool (and maybe less error prone and more intuitive) if we would have this referring to our Atomic<T> or T object itself.

We need a function that allows us the set the new value and a function that let us read or modify our T as this. I came up with these two:

withLock allows us to use a lambda that can use value as this. That enables you to use functions from T without any boilerplate. You can either manipulate this directly or just read (and return) whatever you need in a consistent blocked way.

setWithLock allows us to put in a lambda that receives the current value of our Atomic<T> and saves the returned value as new state. That makes nicer code as your T object stays immutable.

An interesting code gimmick of Kotlin is the way to call the original Mutex.withLock function. Issue here - Mutex.withLock is not a member, but an extension function (see also the extra import line). So you can’t reach it with super.withLock, but you need to cast your object to a Mutex, to reach out for Mutex.withLock.

Everything put together with an example program to run:

Hope you enjoyed. Ideas and remarks are welcome.

--

--