3 回答

TA貢獻1802條經驗 獲得超4個贊
問題在public synchronized void run() { 相當于 synchronized(this),而 main中
new Thread(new Test16(0,2,100)).start();
new Thread(new Test16(1,2,100)).start();
這樣是2個不同的test16對象,因而是2個不同的鎖,2個鎖都在等待自己的資源(2個線程都停止了),所以不可能被喚醒。其實樓主想鎖定的是共享的counter,counter的是static的,屬于類對象,所以要在類上加鎖才行。
代碼修改如下:
public void run() {
synchronized (Test16.class) {
while (counter < sum) {
while (turn != counter % num) {
try {
Test16.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
counter++;
System.out.println(counter + " turn : " + turn);
Test16.class.notifyAll();
}
}
}

TA貢獻1856條經驗 獲得超17個贊
樓主,根本原因是你這里用了兩個不同的對象,是不會實現互斥效果的
引用
new Thread(new Test16(0,2,100)).start();
new Thread(new Test16(1,2,100)).start();
這里兩個Test16的對象,每個對象都可以進入你synchronized 的run方法。
這了互斥可以用類似生產者消費者李模式這種概念,或者直接使用阻塞隊列,開始時隊列只存放一個1,兩個線程輪流每次在隊列里取,取到消費后,將加1的結果再放入隊列,此時notifyAll,另一個線程就可以取到數據。當前線程就會阻塞,以此可以實現你要的效果。

TA貢獻1811條經驗 獲得超4個贊
while(turn!=counter%num){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
turn不等于的時候,然后就wait,
線程調用了wait,就會進入休眠狀態并且釋放鎖,直到其他線程調用相同對象的notify或者notifyAll,這個線程才會(notify的話只是有可能會)重新進入執行隊列。當這個線程開始執行的時候它會再次接管鎖并執行wait后面的內容(接管鎖這個動作會等待鎖被其他線程釋放)。
添加回答
舉報