Concurrency - makstron/info GitHub Wiki

Atomic

var i = AtomicInteger()
 
val job1 = launch(Dispatchers.Default) {
   repeat(100000) {
           i.incrementAndGet()
   }
}
 
val job2 = launch(Dispatchers.Default) {
   repeat(100000) {
           i.incrementAndGet()
   }
}
 
job1.join()
job2.join()

synchronized

val job1 = launch(Dispatchers.Default) {
   repeat(100000) {
           increment()
   }
}
 
val job2 = launch(Dispatchers.Default) {
   repeat(100000) {
       increment()
   }
}
 
job1.join()
job2.join()

//////

var i = 0
 
@Synchronized
fun increment() {
   i++
}

Mutex

val job1 = launch(Dispatchers.Default) {
   repeat(100000) {
           increment()
   }
}
 
val job2 = launch(Dispatchers.Default) {
   repeat(100000) {
       increment()
   }
}
 
job1.join()
job2.join()

//////

val mutex = Mutex()
var i = 0
 
suspend fun increment() {
   mutex.withLock {
       i++
   }
}

Lock

Класс Lock выполняет примерно те же функции, что и synchronized, только более гибко. synchronized даёт возможность синхронизировать блоки кода, тогда как с Lock можно реализовывать более сложную логику.

import kotlinx.coroutines.*
import java.util.concurrent.locks.ReentrantLock

class Incrementor() {
    private val sharedCounterLock = ReentrantLock()
    var sharedCounter: Int = 0
        private set

    fun updateCounterIfNecessary(shouldIActuallyIncrement: Boolean) {
        if (shouldIActuallyIncrement) {
            try {
                sharedCounterLock.lock()
                sharedCounter++
            } finally {
                sharedCounterLock.unlock()
            }
        }
    }
}

fun main() = runBlocking {
    val incrementor = Incrementor()
    val scope = CoroutineScope(newFixedThreadPoolContext(4, "synchronizationPool"))
    scope.launch {
        val coroutines = 1.rangeTo(1000).map {
            launch {
                for (i in 1..1000) {
                    incrementor.updateCounterIfNecessary(it % 2 == 0)
                }
            }
        }

        coroutines.forEach { corotuine ->
            corotuine.join()
        }
    }.join()

    println("The number of shared counter is ${incrementor.sharedCounter}")
}

Actor

STARTANDROID proglib