Kotlin coroutines Mutex owner 用法

Kotlin coroutines Mutex owner usage

ownerkotlinx.coroutines.sync.Mutex 中的预期用途是什么?

根据我的理解,Mutex.withLock 将在第一个( 锁定互斥体)之后进行任何调用协程,等待直到它被解锁,然后自己持有锁。

那么,是什么导致了以下错误?

2019-12-06 15:29:30.508 6380-6840/com.[...] E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-3
    Process: com.[...], PID: 6380
    java.lang.IllegalStateException: Already locked by [...].source.local.configuration.ConfigurationCacheSourceImpl@c86499c
        at kotlinx.coroutines.sync.MutexImpl.lockSuspend(Mutex.kt:208)
        at kotlinx.coroutines.sync.MutexImpl.lock(Mutex.kt:187)
        at com.[...].source.local.cache.CacheSource.invoke$suspendImpl(CacheSource.kt:52)
        at com.[...].source.local.cache.CacheSource.invoke(Unknown Source:0)
        at com.[...].source.local.cache.ICacheSource$DefaultImpls.invoke$default(CacheSource.kt:10)
        at com.[...].repository.ConfigurationRepositoryImpl.getStuff(ConfigurationRepository.kt:14)
        at com.[...].interactor.ConfigurationInteractorImpl.getStuff(CongifurationInteractor.kt:16)
        at com.[...]
        at com.[...]
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:740)

请注意,我总是在其 withLock 调用中使用相同的 owner,根据:

abstract class CacheSource<T>(
    private val cacheMutex = Mutex()

    override suspend operator fun invoke(
        [...]
    ): T = cacheMutex.withLock(this) {
        [...]
    }
}

根据docs

owner - Optional owner token for debugging. When owner is specified (non-null value) and this mutex is already locked with the same token (same identity), this function throws IllegalStateException.

Mutexowner的用途在相应参数的文档中有说明。协程互斥体是不可重入的,因此在尝试重新获取已获取的锁时进入 "deadlock" 相对容易。此外,在实现复杂的锁定模式(如移交锁定)时,可能很容易搞砸并释放你不应该持有的锁。

所以 owner 是一个可选的调试辅助工具。当指定 owner(非空值)并且互斥量已被同一所有者(相同身份)锁定时,则 lock 函数将抛出 IllegalStateException。同样,尝试 unlock 错误的所有者会抛出 IllegalStateException.

有关详细信息,请参阅有关 lockunlock 函数的文档: