Kotlin 协程 Mutex 作用场景

4,107 阅读1分钟

测试反馈了个bug,大概意思就是 某种场景下,推送消息会被插入到数据库中两次,而我们本来的逻辑是 如果没有消息就插入消息,如果有消息 就更新消息的内容即可, 仔细想想 很快能知道 问题出在 多线程同步这里,同一个方法块 同一个时间点内被执行了,这会导致 判断是否已有消息的条件出现错误,这里的代码是kotlin 协程做的, 所以看下问题怎么解决。

可以看下问题原型:

fun main(){
    var counter=0
    repeat(100){
        GlobalScope.launch {
            println(counter++)
        }
    }

    // 防止主线程直接结束
    Thread.sleep(100000)
}

看下执行结果:

image.png

显然这个结果是不可接收的,已经乱了顺序,其实就是简单的线程同步问题,

看下kotlin中 怎么解决这个问题

fun main(){
    var counter=0
    var mutex= Mutex()
    repeat(100){
        GlobalScope.launch {
            mutex.withLock {
                println(counter++)
            }
        }
    }

    // 防止主线程直接结束
    Thread.sleep(100000)
}

看下结果:

image.png

问题解决了。

再考虑一下另外一种场景,之前我们的mutex 是用在 同一个CoroutineScope中,这里我们试试看,将Mutex 放到 两个不同的同一个CoroutineScope中 看看是否还能生效

fun main(){
    var counter=0
    var mutex= Mutex()
    repeat(100){
        GlobalScope.launch {
            mutex.withLock {
                println(counter++)
            }
        }
    }

    repeat(100){
        CoroutineScope(Dispatchers.IO).launch{
            mutex.withLock {
                println(counter++)
            }
        }
    }

    // 防止主线程直接结束
    Thread.sleep(100000)
}

看下执行结果:

image.png

完美无暇。