1.線程安全
(1)當多個線程訪問一個對象時,如果不考慮這些線程在執行時環境下的調度和交替執行,也不需要進行額外的同步,或者在調用方進行任何其他的協調操作,調用這個對象的行為都可以獲得正確的結果,那麼這個對象時是線程安全的。
(2)Java語言中的線程安全
a)可以將Java語言中各種操作共享的數據分為5類:不可變,絕對線程安全,相對線程安全,線程兼容和線程對立
b) 在Java語言中不可變的對象一定是線程安全的,無論是對象的方法實現還是方的調用者,都不需要再采用任何的線程安全保障措施。
c)線程兼容:是指對象本身不是線程安全的,但是通過在調用端正確地使用同步手段來保證對象在並發環境中可以安全的使用。
d)線程對立:是指無論被調用端是否采取了同步措施,都無法在多線程環境中並發使用代碼。
(3)線程安全的實現方法
a)互斥同步是常見的一種並發正確性保障手段。同步是指在多線程並發訪問共享數據時,保證共享數據在同一時刻只能被一個線程使用。而互斥是實現同步的一種手段,臨界區、互斥量和信號量都是主要的互斥實現方式。
b)在Java中,最基本的互斥同步手段就是synchronized關鍵字,synchronized關鍵字經過編譯後,會在同步代碼塊的前後分別形成monitorenter和monitorexit這兩個字節碼指令,這兩個字節碼都需要一個reference類型的參數來指明要鎖定和解鎖的對象。
c)synchronized同步塊對同一線程來說是可重入的,不會出現自己把自己鎖死的問題。同步代碼塊在已進入的線程執行完之前,會阻塞後面其他線程的進入。
d)除了synchronized之外,還可以使用java.uitl.concurrent包中的重入鎖(ReentrantLock)來實現同步。
e)相比synchronized,ReentrantLock增加了一些高級功能:等待可中斷。可實現公平鎖,以及鎖可以綁定多個條件
等待可中斷:是指持有鎖的線程長期不釋放鎖的時候,正在等待的線程可以選擇放棄等待,改為處理其他事情,可中斷特性對處理執行時間非常長的同步塊很有幫助。
公平鎖:是指多個線程在等待一個鎖時,必須按照申請鎖的時間順序來依次獲得鎖
f)非阻塞同步:基於沖突檢測的樂觀並發策略,也就是說,先進行操作,如果沒有其他線程爭用共享數據,按操作就成功了;如果共享數據有爭用,產生了沖突,那就再采取其他的補償措施,這種樂觀的並發策略的許多實現都是不需要把線程掛起的。
g)無同步方案
可重入代碼:也叫純代碼,可以在代碼執行的任何時刻中斷它,轉而去執行另外一段代碼,而在控制權返回後,原來的程序不會出現任何錯誤。
線程本地存儲。
2.鎖優化
(1)自旋鎖與自適應自旋
為了讓線程等待,只需要讓線程執行一個忙循環(自旋),這項技術就是自旋鎖。
(2)鎖消除
指虛擬機即時編譯器在運行時,對一些代碼上要求同步,但是被檢測到不可能存在共享數據競爭的鎖進行消除。鎖消除的主要判定依據來源於逃逸分析的數據支持。
(3)鎖粗化
擴展(粗化)同步鎖的范圍
(4)輕量級鎖
(5)偏向鎖