我已经创建了一个新的条件chopstickFree
,并且在我的pickUpChopstick()
方法中,我正在等待锁定它,但我根本无法访问它。
通过调试,我发现当它到达chopstickFree.await()
方法中的pickUpChopstick()
行时,它会无限期暂停
public class Chopstick {
Lock lock = new ReentrantLock();
private Condition chopstickFree = lock.newCondition();
private Condition chopstickInUse = lock.newCondition();
Chopstick() {
lock.lock();
chopstickFree.signalAll();
lock.unlock();
}
// Pick up chopstick
public void pickUpChopstick() throws InterruptedException {
lock.lock();
try {
chopstickFree.await(); // ALWAYS PAUSES HERE INDEFINITELY
chopstickInUse.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
// Release chopstick
public void releaseChopstick() {
lock.lock();
chopstickFree.signal();
lock.unlock();
}
}
有什么想法吗?
干杯
答案 0 :(得分:2)
Condition#signalAll()
仅表示当前位于Condition#await()
(或其朋友)中的线程,即信号未排队等待以后的呼叫。
您需要另一个受锁保护的标志才能正确实现:
public class Chopstick {
private final Lock lock = new ReentrantLock();
private final Condition chopstickFree = lock.newCondition();
private volatile boolean isFree = true;
Chopstick() { /* Nothing */ }
// Pick up chopstick
public void pickUpChopstick() throws InterruptedException {
lock.lock();
try {
while (!isFree) {
chopstickFree.await();
}
isFree = false;
} finally {
lock.unlock();
}
}
// Release chopstick
public void releaseChopstick() {
lock.lock();
try {
isFree = true;
chopstickFree.signal();
} finally {
lock.unlock();
}
}
}
这是一个使用Semaphore
的版本,可能与原始实现的距离更近一些:
public class Chopstick {
private final Semaphore chopsticksAvailable = new Semaphore(1);
Chopstick() {
// Nothing
}
// Pick up chopstick
public void pickUpChopstick() throws InterruptedException {
chopsticksAvailable.acquire();
}
// Release chopstick
public void releaseChopstick() {
chopsticksAvailable.release();
}
}