Recently, I came across a component that relied on threads. I wanted to test it’s behaviour. However, soon I came across the issues that come with parallelisation (always have to look up how to spell that word).

val scheduler = Scheduler()
var result: String? = null

scheduler.schedule {
result = "expected value"
}

assertThat(result, equalTo("expected value"))
val scheduler = Scheduler()
val queue = SynchronousQueue<String>()
scheduler.schedule {
queue.put("expected value")
}
assertThat(queue.take(), equalTo("expected value"))

Delegation

Using queues the code looks OK. However, since we are using Kotlin we can make things nicer. We can encapsulate the queue inside of a delegated property.

class FutureValue<A> {
private val queue by lazy { SynchronousQueue<A>() }
operator fun getValue(
thisRef: Nothing?,
property: KProperty<*>
): A = queue.take()
operator fun setValue(
thisRef: Nothing?,
property: KProperty<*>,
value: A
) = queue.put(value)
}

fun <A> future() = FutureValue<A>()
val scheduler = Scheduler()
var result by future<String>()
scheduler.schedule {
result = EXPECTED_VALUE
}
assertEquals(result, EXPECTED_VALUE)

Coroutines

When writing this I thought about using coroutines and channels.

runBlocking {
val scheduler = Scheduler()
val channel = Channel<String>()
scheduler.schedule {
launch { channel.send(EXPECTED_VALUE) }
}
assertEquals(channel.receive(), EXPECTED_VALUE)
}
class AsyncValue<A> {
private val channel by lazy { Channel<A>() }
operator fun getValue(
thisRef: Nothing?,
property: KProperty<*>
): A = runBlocking { channel.receive() }
operator fun setValue(
thisRef: Nothing?,
property: KProperty<*>,
value: A
) = launch { channel.send(value) }
}

fun <A> async() = AsyncValue<A>()
var result by async<String>()
Image for post
Image for post
Times on the different methods of suspension

Back to basics

I mentioned the use of the old fashioned wait/notify combo before. And even though on its own is a bit complicated, once hidden away in a delegated property, it looks exactly the same as the others ones.

Show me what you got!

The code I produced for this article can be found here:

Image for post
Image for post

Written by

Software Artisan

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store