先來舉例說明線程不安全是什麼狀況下發生的:例如一個變量能夠被多個線程進行訪問,那麼在大量線程併發訪問這個變量的狀況下,線程執行的順序會給最後的結果帶來不可預估的錯誤。
先定義一個單例類SimpleWorkingHardSingleton:編程
public class SimpleWorkingHardSingleton { private static SimpleWorkingHardSingleton simpleSingleton = new SimpleWorkingHardSingleton(); // 數量 private int count; private SimpleWorkingHardSingleton() { count = 0; } public static SimpleWorkingHardSingleton getInstance() { return simpleSingleton; } public int getCount() { return count; } public void addCount(int increment) { this.count += increment; System.out.println(this.count); } }
能夠看到下面這個單例若在多線程環境下運行,count是被多個線程同時操縱的變量,示例:安全
for (int i = 0; i < 5; i++) { new Thread(new Runnable() { @Override public void run() { SimpleWorkingHardSingleton simpleSingleton = SimpleWorkingHardSingleton.getInstance(); simpleSingleton.addCount(1); } }).start(); }
看輸出結果(你的執行結果可能和個人不一樣):多線程
3 2 2 4 5
匪夷所思的結果,想不懂爲何會有兩個2出現,1哪兒去了,爲何輸出不是 1 2 3 4 5,下面就來解釋一下併發
其實咱們看到線程安全性的定義的關鍵點在於正確性,即在多線程的環境下,不管運行時候環境採用如何的調度方式,系統或者類或者方法總能表現出預期的相符的行爲,那麼就是線程安全的。ide