Java併發編程實戰筆記(1):線程安全性-什麼是線程安全性

線程的安全的定義是複雜的,安全性中最核心的概念就是數據的正確性。


正確性

當多個線程訪問某個類時,這個類始終能表現出正確的行爲,那麼就稱這個類是安全的。

如果我們還是不懂這個正確性的定義,就舉一個反例來理解它。

public class ThreadSecStudy {
    static int count = 0;
    public static void main(String[] args) {
        // 正確性反例
        Thread add = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    count++;
                    System.out.println(count);
                }
            }
        });
        Thread cut = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    count--;
                    System.out.println(count);
                }
            }
        });

		// 加法
        add.start();
        // 減法
        cut.start();
    }
}

一定會有人覺得這段代碼從邏輯上是沒有任何問題的,一加一減並且相同的次數,那麼結果一定等於0,這是我們心中的認爲的正確的行爲,但是實際上呢,最後輸出的並不是0。

-70
-69
-68
-67

而且每次的輸出都是不相同的,其中循環的次數越多偏差越大,與我們的正確性的概念是完全相反的,也就是說這個類是不安全的。


三個體現

  • 原子性:提供互斥訪問,同一時刻只能有一個線程對數據進行操作(Atomic、CAS算法、synchronized、Lock)
  • 可見性:一個主內存的線程如果進行了修改,可以及時被其他線程觀察到(synchronized、volatile)
  • 有序性:如果兩個線程不能從 happens-before原則 觀察出來,那麼就不能觀察他們的有序性,虛擬機可以隨意的對他們進行重排序,導致其觀察觀察結果雜亂無序(happens-before原則)

我們就按照這幾個體現,來改造之前存在的不安全的類。


詳細介紹參考以下文章!


文章中出現的任何錯誤歡迎指正,共同進步!

最後做個小小廣告,有對WEB開發和網絡安全感興趣的,可以加羣一起學習和交流!

交流羣
QQ:425343603

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章