gpt4 book ai didi

java - 可重入锁在 Java 中工作正常,但在 Scala 中导致 IllegalMonitorException

转载 作者:行者123 更新时间:2023-12-01 21:40:48 25 4
gpt4 key购买 nike

我想迁移 Java 函数

protected static final Lock LOCK = new ReentrantLock();
public double calculate(...){
try {
LOCK.tryLock(20, TimeUnit.SECONDS);
...
}finally{
LOCK.unlock()
}
}

Scala 中的相同函数:

protected final def LOCK = new ReentrantLock
def calculate(...): double = {
try{
LOCK.tryLock(20, TimeUnit.Seconds)
...
}finally{
LOCK.unlock()
}
}

LOCK.unlock() 总是导致 IllegalMonitorStateException。我不明白为什么会发生这种情况。

谁能告诉我问题出在哪里吗?

最佳答案

您绝对应该将LOCK设置为val而不是def。就目前情况而言,您每次都会重新创建一个新的 ReetrantLock 实例。实际上,您正在做的是:

try {
// Useless as we are creating a new lock
(new ReentrantLock).tryLock(20, TimeUnit.SECONDS).tryLock(20, TimeUnit.SECONDS).tryLock(20, TimeUnit.SECONDS);
...
}finally{
// Useless too, and will actually throw because we unlock a fresh (thus unlocked) lock
(new ReentrantLock).unlock()
}

这显然注定会失败。

你应该这样做:

object MyClass {
private val LOCK = new ReentrantLock
}
class MyClass {
def calculate(...): double = {
try{
LOCK.tryLock(20, TimeUnit.Seconds)
...
}finally{
LOCK.unlock()
}
}
}

这是原始 java 代码到 scala 的直接翻译。

最后,乔恩·斯基特(Jon Skeet)在他(现已删除)的回答中正确地建议:

You should only unlock the lock if you managed to acquire it - and the conventional pattern is to put the lock/tryLock call before the try. (It doesn't matter with tryLock(), but it does matter for lock(), so we might as well be consistent.)

这给出:

object MyClass {
private val LOCK = new ReentrantLock
}
class MyClass {
def calculate(...): double = {
val gotLock = LOCK.tryLock(20, TimeUnit.Seconds)
try {
...
} finally {
if (gotLock) {
LOCK.unlock()
}
}
}
}

关于java - 可重入锁在 Java 中工作正常,但在 Scala 中导致 IllegalMonitorException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36495283/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com