對不起,如果這是非常明顯的或已在其他地方回答。我一直無法找到任何東西。我有以下代碼:Java同步混淆
public class SimpleThread extends Thread {
public static Integer sharedVal = 0;
public SimpleThread() {
}
@Override
public void run() {
while(true) {
iterator();
}
}
public void theSleeper() {
System.out.println("Thread: " + this.getId() + " is going to sleep!");
try {
this.sleep(5000);
} catch(Exception e) {
}
}
public void iterator() {
synchronized(sharedVal) {
System.out.println("Iterating sharedVal in thread: " + this.getId());
sharedVal++;
System.out.println(sharedVal);
theSleeper();
System.out.println("Thread : " + getId() + " is done sleeping, trying to iterate again...");
}
}
}
我創建了這個SimpleThread類的兩個實例,並執行run方法。我期望看到像這樣的東西:線程9遞增...線程9睡眠...(5秒後)線程10遞增....線程10睡眠...。我期望這是因爲我鎖定了迭代器方法,以便一次只能有一個線程能夠輸入它。相反,兩個線程都會增加,然後等待5秒鐘。這永遠重複。我在這裏錯過了什麼,以便得到預期的行爲?非常感謝!
編輯:我做了一個新的公共靜態變量:public static Object theLock = new Object()。現在,在迭代器方法中,我確實同步了(theLock)。現在輸出更像我所期望的那樣,因爲鎖永遠不會改變。但是,現在只有線程9進入該方法。看來,線程10正在捱餓,並且永遠不會回合。這似乎很奇怪。這不只是幾次,它總是隻是線程9迭代和睡眠。我會認爲這將是9,10,9,10。或者可能是一個隨機分佈像9,10,10,10,9,10,9,9,10等
編輯2:我看到什麼是正在發生。線程9有鎖。線程10嘗試進入該功能,但被立即告知要等待。函數完成後,它可能仍然是線程9轉。線程9然後獲得鎖,並且循環繼續。線程10得到一個回合的時間窗口非常小,如果它確實得到了回合,它可能會捱餓9.也就是說,在iterator()中的synchronized塊之後放置yield()看起來並沒有使它更多公平。我閱讀了關於該方法的評論,而調度器實際上可以忽略yield()。
自動裝箱是魔鬼 –
哈哈哈,現在看來,這可能是有問題的! :) – user2045279