簡體   English   中英

了解線程干擾 (Java)

[英]understind thread interference (Java)

我試圖了解什么是線程干擾。 這是Java官網關於線程干擾的解釋。

線程 A:檢索 c。
線程 B:檢索 c。
線程A:遞增檢索值; 結果是 1。
線程B:遞減檢索值; 結果是-1。
線程A:將結果存儲在c中; c 現在是 1。
線程 B:將結果存儲在 c 中; c 現在是 -1。

所以我添加了代碼來查看 c 的變化。

在圖片(第 4 行)中,第 1 次減量:(檢索 C)0不應該是 -1 嗎? 為什么是0?

此外,如果您看到以下結果,則第 2 次遞減:(檢索 C)為 -1。

我認為第 2 次減量(減少 C)應該是 -2,但它仍然是 -1。

我不明白。 有人可以解釋我的reslt嗎?

第 2 次減量:(檢索 C)-1

第 2 次遞減(減少 C)-1

在此處輸入圖像描述

public class Counter {
private int c = 0;
public void increment(){
    for(int i=0; i<1000; i++){
        System.out.println(i + "th increment:(Retrieve  C) " + c);
        c++;
        System.out.println(i + "th increment:(Increased C) " + c);
    }
}
public void decrement(){
    for(int i=0; i<1000; i++){
        System.out.println(i + "th decrement:(Retrieve  C) " + c);
        c--;
        System.out.println(i + "th decrement(Decreased C) " + c);
    }
}
public int getC(){
    return c;
}

public static void main(String[] args) throws InterruptedException{
    Counter c = new Counter();
    Thread t1 = new Thread(() -> {
        c.increment();
    });
    Thread t2 = new Thread(() -> {
        c.decrement();

    });

    t1.start();
    t2.start();

    t1.join();
    t2.join();

}

}

c++; 實際上做了三件事,一件接一件。

  1. 它讀取c的值。
  2. 它增加了它所看到的。
  3. 它將新值保存回c

這些操作不是原子的,這意味着不能保證c在執行此操作時不會獨立更改。 同樣對於c--; .

因此,雖然您有兩個線程對同一個變量c執行類似的操作,但其中一個線程很可能會更改c而另一個線程正在執行其工作。 這似乎就是你所看到的。

事實上,通過在兩個線程中打印c ,您增加了其中一個線程在另一個線程打印其兩條消息的時間之間更改c值的可能性。

“干涉”一詞沒有官方含義。 您的代碼存在 2 個問題

  1. 競爭條件:因為讀寫不是原子的,因此您可能會遇到丟失的更新。

  2. 數據競爭:因為對“c”變量的訪問不同步,所以沒有發生之前的邊緣。 要深入了解,需要深入了解 Java Memory Model。

這兩個問題都可以通過將 'c' 設為 AtomicInteger 並使用遞增/遞減方法來輕松解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM