KMM中@Synchronized注解未按预期生效问题求助
问题根源
@Synchronized 注解失效的核心原因是:你在 test 函数内部用 CoroutineScope.launch 启动了异步协程,函数本身会立即执行完毕并返回,同步锁仅控制了函数的进入时机,却无法约束协程内部的异步逻辑执行完成。所以后续调用会直接进入函数,启动新的协程,完全达不到你要的“等待操作完成后再允许其他调用”的效果。
解决方案
要实现协程环境下的同步等待,应该使用协程友好的互斥锁 Mutex,而非Java的@Synchronized。同时需要将test改为挂起函数,确保内部逻辑执行完成后才释放锁。
修改后的代码示例
// 在类内部定义协程互斥锁 private val testMutex = Mutex() fun ktorFunction(){ HttpResponseValidator { handleResponseException { exception -> kermit.e { "In ${exception.message}" } val clientException = exception as? ClientRequestException ?: return@handleResponseException val exceptionResponse = clientException.response when (exceptionResponse.status) { HttpStatusCode.Unauthorized -> { // 直接调用挂起函数(handleResponseException本身是挂起上下文) test { kermit.v { "Error message" } } } } } } } // 改为挂起函数,用Mutex实现协程同步 suspend fun test(messageTest: () -> Unit) { testMutex.withLock { delay(3000) messageTest() // 这里可以添加任何需要同步执行的逻辑,都会等待完成后再释放锁 } }
关键说明
Mutex是Kotlin协程提供的同步工具,withLock会挂起当前协程(而非阻塞线程),直到锁被释放,完美适配Ktor的非阻塞协程环境。- 所有进入
withLock块的逻辑都会串行执行,必须等待前一次调用的所有操作(包括delay、业务逻辑)完成后,下一次调用才能进入。 - 避免使用
runBlocking来阻塞线程实现同步,这会破坏Ktor的非阻塞特性,降低性能。
内容的提问来源于stack exchange,提问作者Svilen Rusev
相关产品推荐
相关产品推荐

