You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用Mutex同步修改共享状态的函数?runBlocking场景解析

正确在Kotlin协程中使用Mutex同步共享状态的方案

这个问题我之前帮不少开发者排查过,核心误区其实是混淆了Kotlin Mutex的阻塞式API和挂起式API——尤其是在runBlocking这种「阻塞线程来运行协程」的场景下,误用阻塞API就会导致你遇到的线程长时间卡住的问题。

先搞懂关键区别:Mutex的两种锁定方式

Kotlin协程的Mutex有两类API:

  • 阻塞式:lock()和unlock(),这两个方法会直接阻塞当前线程,直到锁被获取/释放。这种方式完全不适合协程场景,尤其是runBlocking,因为它会占用协程绑定的线程,导致其他协程无法调度。
  • 挂起式:withLock { ... },这是协程友好的挂起函数。当锁被占用时,它会释放当前线程,让其他协程可以继续执行,直到锁可用时再恢复执行。这才是我们应该在协程中使用的方式。

为什么runBlocking里用阻塞lock会出问题?

runBlocking的本质是「在当前线程上启动一个协程调度器,并且阻塞这个线程直到协程执行完毕」。如果你在runBlocking内部的协程里调用了mutex.lock(),这个线程会被直接卡住——哪怕其他协程也需要获取这个锁,它们也无法得到调度(因为线程被占着),最终导致线程长时间阻塞,甚至死锁。

正确用法示例(适用于所有协程启动方式)

不管你是用launch/async还是runBlocking启动协程,都应该用withLock来同步共享状态:

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

// 共享状态
var sharedCounter = 0
val mutex = Mutex()

fun main() = runBlocking {
    // 多线程调用场景:用Dispatchers.Default(多线程调度器)启动多个协程
    val jobs = List(10) {
        launch(Dispatchers.Default) {
            repeat(1000) {
                // 用挂起式的withLock同步修改共享状态
                mutex.withLock {
                    sharedCounter++
                }
            }
        }
    }
    jobs.forEach { it.join() }
    println("最终计数:$sharedCounter") // 应该输出10000
}

多线程调用场景的注意事项

  1. 不要依赖线程限制:你提到无法用线程限制方案,而Mutex的withLock本身就是跨线程安全的——不管协程运行在哪个线程上,withLock都会保证同一时间只有一个协程能进入代码块,完全不需要限制线程。
  2. 避免在withLock里调用阻塞操作:虽然withLock是挂起友好的,但如果在代码块里调用了阻塞线程的操作(比如Thread.sleep()),还是会占用线程,影响协程调度。如果必须用阻塞操作,建议用withContext(Dispatchers.IO)包裹,把阻塞操作放到IO调度器的线程池里。

错误用法示例(需要避免)

下面这种用阻塞式lock()/unlock()的写法,在runBlocking里会导致线程长时间阻塞,甚至死锁:

// 错误示例!不要这么写
fun main() = runBlocking {
    launch {
        mutex.lock() // 阻塞当前线程
        try {
            sharedCounter++
            // 如果这里有耗时操作,线程会一直被占着
        } finally {
            mutex.unlock()
        }
    }
}

总结一下:只要你始终使用mutex.withLock { ... }这个挂起式API,不管是在launch/async还是runBlocking启动的协程里,都能正确同步共享状态,不会出现线程长时间阻塞的问题。

内容的提问来源于stack exchange,提问作者user221256

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:11:32