線程安全性的定義:
當多個線程訪問某個類時,不管運行時環境採用何種調度方式或者這些線程將如何交替執行,並且在主調代碼中不需要任何額外的同步或協同,這個類都能表現出正確的行爲,那麼就稱這個類是線程安全的。
主要誘因:
存在可變的共享數據,並且同時有多條線程共同操作這些資源
實現線程安全:
線程封閉:線程封閉的對象只能由一個線程擁有,對象被封閉在該線程中,並且只能由這個線程修改。
只讀共享:在沒有額外同步的情況下共享的只讀對象可以由多個線程併發訪問,但任何線程都不能修改它。共享的只讀對象包括不可變對象和事實不可變對象。
線程安全共享:線程安全的對象在其內部實現同步,因此多個線程可以通過對象的公有接口來進行訪問而不需要進一步的同步。
保護對象:被保護的對象只能通過持有特定的鎖來訪問。保護對象包括封裝在其他線程安全對象中的對象,以及已發佈的並且由某個特定鎖保護的對象。
三大特徵:
①原子性
指定代碼塊是原子操作,線程的多個操作是一個整體,不能被分割,要麼就不執行,要麼就全部執行完,中間不能被打斷。
②可見性
修改共享變量時,立即同步到主存中,並使該修改對其他線程可見
③有序性
爲了提高執行效率,java中的編譯器和處理器可以對指令進行重新排序,重新排序會影響多線程併發的正確性,有序性就是要保證不進行重新排序(保證線程操作的執行順序)。
注:需要都滿足才能夠確保線程安全,比如volatile就只實現了可見性和有序性,而沒有實現原子性,因此並不能夠保證線程安全