簡體   English   中英

Java線程安全計數器

[英]Java Thread Safe Counter

我正在學習編寫線程安全程序以及如何評估不是線程安全的代碼。

如果一個類在由多個線程執行時可以正常運行,則認為該類是線程安全的。

我的Counter.java不是線程安全的,但是對於所有3個線程,輸出均按預期從0-9打印。

誰能解釋為什么? 以及線程安全性如何工作?

public class Counter {

    private int count = 0;

    public void increment() {
        count++;
    }

    public void decrement() {
        count--;
    }

    public void print() {
        System.out.println(count);
    }

}

public class CountThread extends Thread {
    private Counter counter = new Counter();

    public CountThread(String name) {
        super(name);
    }

    public void run() {
        for (int i=0; i<10; i++) {
            System.out.print("Thread " + getName() + " ");
            counter.print();
            counter.increment();
        }
    }

}

public class CounterMain {

    public static void main(String[] args) {
        CountThread threadOne = new CountThread("1");
        CountThread threadTwo = new CountThread("2");
        CountThread threadThree = new CountThread("3");

        threadOne.start();
        threadTwo.start();
        threadThree.start();
    }

}

您的Counter不是通過3個線程共享的,而是每個線程都有一個唯一的Counter

您的代碼在特定測試中運行良好。 這並不意味着它將一直正常工作。 嘗試進行更多次迭代,您可能會開始發現異常。

您的測試有點像您測試過一座橋可以乘坐一輛汽車在橋上行駛時可以支撐20輛卡車。 它沒有顯示任何東西。 並且使用測試來證明代碼是線程安全的幾乎是不可能的。 只有仔細閱讀並理解所有潛在問題才能保證這一點。 非線程安全程序可能會正常運行數年,並且突然出現錯誤。

為了使您的櫃台安全,請使用AtomicInteger。

編輯:

另外,正如@SpringRush所指出的,您沒有在線程之間共享單個計數器。 每個線程都有其自己的計數器。 因此,您的代碼實際上是線程安全的,但我認為它沒有達到您的預期目的。

所以這實際上是線程安全的。 對於每個CountThread,都有一個計數器。 為了使其不是線程安全的,請將計數器變量更改為:

private static Counter counter = new Counter(); 

這樣就不是線程安全的,因為不同的線程可能會同時修改計數器狀態。

試試這個:

public class ThreadSafeCounter {

    AtomicInteger value = new AtomicInteger(0);

public ThreadSafeCounter(AtomicInteger value) {
    this.value = value;
}

public void increment() {
    value.incrementAndGet();
}

public void decrement() {
    value.decrementAndGet();
}

public AtomicInteger getValue() {
    return value;
}

}

暫無
暫無

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

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