我想了解Java中多個線程的同步更充分。我瞭解使用synchronized關鍵字的高層次思想,以及它如何在線程間提供互斥。Java同步方法和塊
唯一的問題是,即使您刪除了使該主題比我認爲需要更加混淆的同步關鍵字,但我在線閱讀和我的教科書中的大多數示例仍然正常工作。
任何人都可以提供一個具體的例子,當不包括同步關鍵字會產生錯誤的結果嗎?任何信息將不勝感激。
我想了解Java中多個線程的同步更充分。我瞭解使用synchronized關鍵字的高層次思想,以及它如何在線程間提供互斥。Java同步方法和塊
唯一的問題是,即使您刪除了使該主題比我認爲需要更加混淆的同步關鍵字,但我在線閱讀和我的教科書中的大多數示例仍然正常工作。
任何人都可以提供一個具體的例子,當不包括同步關鍵字會產生錯誤的結果嗎?任何信息將不勝感激。
通常可以通過增加迭代次數來觸發競爭條件。下面是一個簡單的例子,它可以在迭代100次和1000次的情況下工作,但在10,000次迭代(有時)時失敗(至少在我的四核機器上)。
public class Race
{
static final int ITERATIONS = 10000;
static int counter;
public static void main(String[] args) throws InterruptedException {
System.out.println("start");
Thread first = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
counter++;
}
}
});
Thread second = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
counter++;
}
}
});
first.start();
second.start();
first.join();
second.join();
System.out.println("Counter " + counter + " should be " + (2 * ITERATIONS));
}
}
>>> Counter 12325 should be 20000
此示例失敗,因爲對counter
的訪問未正確同步。它可能以兩種方式失敗,可能同時運行:
該簡單程序的修復方法是使用AtomicInteger
。使用volatile
是不夠的,由於增量的問題,但AtomicInteger
提供增量,獲取和設置等原子操作。
關於競爭條件的事情是,他們不需要必然發生如果你沒有做適當的同步 - 事實上,相當頻繁它會工作得很好 - 但一年後,在中間夜晚,您的代碼將會崩潰,並且會發生無法重現的完全不可預知的錯誤,因爲該錯誤只會隨機出現。
競爭條件如此陰險正是因爲他們不總是總是使您的程序崩潰,並且它們或多或少地隨機觸發。
你看過[Race Conditions](http://en.wikipedia.org /維基/ Race_condition#計算)?這個頁面上有一個很好的例子。 – condit
我看了一下這個例子,但是它的抽象類。我瞭解競賽條件背後的想法,我只想看看它在行動中的一個例子,以幫助我更好地理解它 – Ockham