就上下文而言,这是一款二十一点游戏,因此庄家、玩家、手值和其他术语均来自于此。
obLock 是一个 ReentrantLock,dealerDone 是该锁的条件。
过去,我做过同样的方法,在类中有一个静态锁,我用它来锁定方法/方法的一部分,等待来自条件的信号,然后在完成后解锁该方法
根据我的理解,当我尝试执行等待条件时,如果我没有拥有 oblock,我应该只会收到 IllegalMonitorStateException。这是有道理的,因为我在等待/发出信号时将其锁定在两侧,但这就是我过去的做法,也是我被教导的方式。
这是我等待条件的代码
obLock.lock();
try {
dealerDone.await();
}
catch (InterruptedException ignored) {}
finally {
obLock.unlock();
}
这是我发出信号的代码
obLock.lock();
try {
while (dealerHand < dealer.getBreakpoint()) {
drawCard(dealer);
dealerHand = dealer.getHandValue();
}
dealerDone.signalAll();
} finally {
obLock.unlock();
}
声明我的锁/状况
private static Lock obLock = new ReentrantLock();
private static Condition dealerDone = obLock.newCondition();
我尝试将其变成同步块(尽管我们在课堂上没有学过它们,所以我对它们不是很熟悉),但它给了我同样的问题。
我尝试过制作两把不同的锁,这样它们就不会同时锁定,但我认为这更多地与玩家之间的互动有关,而不是庄家与玩家之间的互动。
lock()
不会获取对象的“固有锁”,而这正是 await()
和 signalAll()
的工作原理。唯一的方法是使用同步块:
synchronized (obj) {
obj.await(); // typically within a "while" loop, to await that condition
}