js css html

kotlin<第十二篇>:协程并发安全

2023-02-25  本文已影响0人  NoBugException
(1)不安全的并发访问

我们使用线程在解决并发问题的时候总是会遇到线程安全的问题,而Java平台上的Kotlin协程实现免不了存在并发调度的情况,因此线程安全同样值得留意。

runBlocking {

    var count = 0
    List(1000) {
        GlobalScope.launch { count++ }
    }.joinAll()
    println(count)

}

打印出来的count值并不是1000。

(2)协程并发安全

在Java中,提供了原子性的对象:AtomicInteger,可以保证协程的安全性:

runBlocking {
    var count = AtomicInteger(0)
    List(1000) {
        GlobalScope.launch { count.incrementAndGet()}
    }.joinAll()
    println(count)
}

除了我们在线程中常用的解决并发问题的手段之外,协程框架也提供了一些并发安全工具,包括:

Mutex演示:

runBlocking {
    var count = 0
    val mutex = Mutex()
    List(1000) {
        GlobalScope.launch {
            mutex.withLock { count++ }
        }
    }.joinAll()
    println(count)
}

Semaphore演示:

runBlocking {
    var count = 0
    val semaphore = Semaphore(1)
    List(1000) {
        GlobalScope.launch {
            semaphore.withPermit { count++ }
        }
    }.joinAll()
    println(count)
}
(3)避免访问外部可变状态

编写函数时要求它不得访问外部状态,只能基于参数做运算,通过返回值提供运算结果。

runBlocking {
    var count = 0
    var result = count + List(1000) {
        GlobalScope.async { 1 }
    }.map { it.await() }.sum()
    println(result)
}

[完...]

上一篇 下一篇

猜你喜欢

热点阅读