public class Stack {
private LinkedList list = new LinkedList();
public synchronized void push(Object x) {
synchronized (list) {
list.addLast(x);
notify(); // 錯誤 1:鎖對象不一致
}
}
public synchronized Object pop() throws Exception {
synchronized (list) {
if (list.size() <= 0) {
wait(); // 錯誤 2:同樣鎖對象不一致
}
return list.removeLast();
}
}
}
| 問題 | 說明 |
|---|---|
| 鎖對象不一致 | 方法用 synchronized(this),內部塊用 synchronized(list),notify()/wait() 作用於 this,但線程實際持有 list 鎖,導致通知遺漏 |
| 虛假喚醒 | wait() 應置於 while 迴圈而非 if |
| 活鎖風險 | 多生產者/消費者時,notify() 可能喚醒同類線程(生產者喚醒生產者),導致無效切換 |
| 異常處理 | wait() 拋出 InterruptedException 需處理 |
public class StackFixed {
private final LinkedList
this 即可,移除內部 synchronized(list))wait() 配合 while 判斷條件notifyAll() 避免活鎖此題考察對監視器鎖、條件隊列、喚醒機制的深度理解。