我的一位同事就ReentrantReadWriteLock
在一些 Scala 代码中使用 Java 进行了如下陈述:
在这里获取锁是有风险的。它是“可重入的”,但这在内部取决于线程上下文。
F
可以在不同线程中运行相同计算的不同阶段。你很容易造成死锁。
F
这里指的是一些有效的单子。
基本上我要做的是在同一个单子中两次获取相同的可重入锁。
有人可以澄清为什么这可能是一个问题吗?
代码分为两个文件。最外层:
val lock: Resource[F, Unit] = for {
// some other resource
_ <- store.writeLock
} yield ()
lock.use { _ =>
for {
// stuff
_ <- EitherT(store.doSomething())
// other stuff
} yield ()
}
然后,在store
:
import java.util.concurrent.locks.{Lock, ReentrantReadWriteLock}
import cats.effect.{Resource, Sync}
private def lockAsResource[F[_]](lock: Lock)(implicit F: Sync[F]): Resource[F, Unit] =
Resource.make {
F.delay(lock.lock())
} { _ =>
F.delay(lock.unlock())
}
private val lock = new ReentrantReadWriteLock
val writeLock: Resource[F, Unit] = lockAsResource(lock.writeLock())
def doSomething(): F[Either[Throwable, Unit]] = writeLock.use { _ =>
// etc etc
}
writeLock
两段代码中的 the 是相同的,它是一个cats.effect.Resource[F, Unit]
包装ReentrantReadWriteLock
a writeLock
。我以这种方式编写代码有一些原因,所以我不想深入研究。我只是想了解为什么(至少根据我的同事的说法),这可能会破坏一些东西。
另外,我想知道 Scala 中是否有一些替代方法可以允许这样的事情而不会出现死锁的风险。