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}")
}