我不确定以下实现是否正确。我的理由是,如果当前线程在等待发出信号时被中断,则会调用finally
块,但由于它没有持有锁,因此将抛出IllegalMonitorStateException
。在这种情况下,我是否正确实施了try-finally
块,或者应该实现一个块?
public void acquire() throws InterruptedException {
try {
lock.lockInterruptibly();
while (permits == 0) {
condition.await();
}
permits--;
}
finally {
lock.unlock();
}
}
答案 0 :(得分:1)
不确定我是否正确理解问题,但您应该尝试 - 在分配资源后最终只
public void acquire() throws InterruptedException {
lock.lockInterruptibly(); // allocate resource before try
try {
while (permits == 0) {
condition.await();
}
permits--;
}
finally {
lock.unlock();
}
}
我不知道为什么所有的学校,例如Sun's official page on finally,建议在finally子句中分配try(以便你需要if(allocated) {release}
)。这是愚蠢的IMO。为什么每个人都建议在try中分配?
答案 1 :(得分:1)
一个好问题。我自己对结果感到惊讶。
如果发生InterruptedException
,则条件将停止awaiting
,然后执行finally
。显然不会拥有锁并传播IllegalMonitorStateException
。
答案 2 :(得分:0)
这个解决方案怎么样?
public void acquire() throws InterruptedException {
lock.lockInterruptibly();
while (permits == 0) {
condition.await();
}
try {
permits--;
}
finally {
lock.unlock();
}
}
当await
返回时,当前线程将具有锁定。如果它在等待其他线程发出信号时被中断(即它没有锁定),acquire
会将InterruptedException
反馈给调用者。