Skip to content

Instantly share code, notes, and snippets.

@SalomonBrys
Created August 17, 2019 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SalomonBrys/688b2ccc10e3a7cea47966bf57d1cf89 to your computer and use it in GitHub Desktop.
Save SalomonBrys/688b2ccc10e3a7cea47966bf57d1cf89 to your computer and use it in GitHub Desktop.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.sync.withPermit
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
import kotlin.system.measureTimeMillis
sealed class CounterMsg
object IncCounter : CounterMsg()
class GetCounter(val response: CompletableDeferred<Int>) : CounterMsg()
suspend fun massiveRun(action: suspend () -> Unit) {
val n = 1000 // number of coroutines to launch
val k = 1000 // times an action is repeated by each coroutine
val time = measureTimeMillis {
coroutineScope {
repeat(n) {
launch {
repeat(k) { action() }
}
}
}
}
println("Completed ${n * k} actions in $time ms")
}
@ObsoleteCoroutinesApi
fun CoroutineScope.counterActor() = actor<CounterMsg> {
var counter = 0
for (msg in channel) {
when (msg) {
is IncCounter -> counter++
is GetCounter -> msg.response.complete(counter)
}
}
}
@ObsoleteCoroutinesApi
fun main() {
runBlocking {
println("With Mutex:")
var counter = 0
val mutex = Mutex()
withContext(Dispatchers.Default) {
massiveRun {
mutex.withLock {
counter++
}
}
}
println("Counter = $counter")
}
runBlocking {
println("With Semaphore:")
var counter = 0
val semaphore = Semaphore(1)
withContext(Dispatchers.Default) {
massiveRun {
semaphore.withPermit {
counter++
}
}
}
println("Counter = $counter")
}
runBlocking {
println("With Lock:")
var counter = 0
val lock = ReentrantLock()
withContext(Dispatchers.Default) {
massiveRun {
lock.withLock {
counter++
}
}
}
println("Counter = $counter")
}
runBlocking {
println("With Actor:")
val counter = counterActor()
withContext(Dispatchers.Default) {
massiveRun {
counter.send(IncCounter)
}
}
val response = CompletableDeferred<Int>()
counter.send(GetCounter(response))
println("Counter = ${response.await()}")
counter.close()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment