协程和 Java 同步不能混用
Posted 码农乐园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了协程和 Java 同步不能混用相关的知识,希望对你有一定的参考价值。
先看一下测试代码
repeat(2)
thread test()
@Synchronized
fun test()
println("Starting!")
Thread.sleep(10)
println("Ending!")
输出结果,没有交叉:
假设我们正在使用协程。那会发生什么?
val scope = CoroutineScope(Job())
repeat(2)
thread test()
@Synchronized
fun test()
println("Starting!")
Thread.sleep(10)
println("Ending!")
在这种情况下,临界区有交错调用
Starting!
Starting!
Ending!
Ending!
了解的是挂起函数实际上并不是逐行执行代码。当一个挂起函数到达一个挂起点时,它会停止该函数的执行并将控制权传递给另一个函数(要理解挂起函数将在稍后恢复)
因此,第二个代码示例中真正发生的是:test()开始,获得锁,打印出“开始!”
它到达delay()(这是一个暂停点),所以它退出函数并释放锁。
随着锁的释放,第二次执行test()开始,获取锁,挂起,释放锁。
当每个延迟完成时,test()再次调用(但在 之后的某个点delay())。
拥有临界区的唯一原因是共享可变状态。因此,我们要解决的真正问题是“我们需要一种控制共享可变状态的方法”。
val mutex = Mutex()
val scope = CoroutineScope(Job())
repeat(2)
scope.launch testLocked()
suspend fun testLocked()
mutex.withLock
println("Starting!")
delay(10)
println("Ending!")
使用synchronized函数但现在想使其暂停的情况下,Mutex是进行该转换的最自然方法.
以上是关于协程和 Java 同步不能混用的主要内容,如果未能解决你的问题,请参考以下文章