JAVA基礎23-多執行緒(三)【synchronized,ReentranLock,volatile、死鎖】
一、同步
大多數多執行緒應用中,兩個或兩個以上的執行緒需要共享對同一資料的存取,此時出現多個程式交替處理該資料,從而導致資料出現訛誤。
9-1.Synchronized關鍵字
兩種用法: 方法和程式碼塊
方法:方法簽名中加入synchronized關鍵字。
程式碼塊:使用synchronized塊對需要進行同步的程式碼段進行同步。
當它用來修飾一個方法或者一個程式碼塊的時,能夠保證在同一時刻最多隻有一個執行緒在執行這段程式碼
9-1-1 synchronized方法
通過在方法宣告中synchronized關鍵字宣告synchronized方法。
(A)當方法是例項方法時,
鎖物件是:當前方法所對應的物件本身。
public synchronized void run(){}
(B) 當方法是靜態方法
鎖物件:是這個類本身
public static synchronized void sd(){}
9-1-2synchronized塊
使用同步方法,其同步範圍會過大,使用synchronized塊,可對方法中的區域性程式碼進行同步處理
synchronized(obj){....}
obj是鎖物件,
obj 若為this,則該鎖物件是呼叫該方法的例項。
obj是 class ,則為類鎖
9-1-3類鎖和物件鎖
類鎖:鎖物件是類,一定會同步。
synchronized(class)和“synchronized修飾靜態方法”。
物件鎖:
鎖物件是例項,只有在單例模式下,鎖才能生效
synchronized(obj)和“synchronized修飾非靜態方法”
(注意:儘量避免使用靜態同步方法,會對效能造成影響)
(注意:物件鎖和類鎖是互不干預的)
(注意:類鎖一定會同步,物件鎖只有在單例模式才生效)
9-2.ReentrantLock類
ReentranLock是Lock的實現類,用ReenTranLock類保護程式碼塊
Lock l=new ReentranLock();
l.lock();
try{
//操作
}
finally{
l.unlock()
}
二、Volatile域
A: 一般來說,同步一個方法用synchronized,同步一個數據,用volatile
B: volatile域具有可見性,而不具備原子性。
C: 如果一個域被volatile修飾,那麼只要對這個域產生寫操作,所有讀操作都可以看到這個修改。
D: 原理:
volatile域會被立刻寫入主記憶體;讀操作則是在主記憶體中。
E: 作用:
volatile不能保證執行緒安全,它只能保護變數安全。主要功能:保護變數不被主函式和中斷函式反覆修改而造成讀寫錯誤。
F: volatile的特性:
保證此變數對所有執行緒的可見性
禁止指令重排序優化。
G: volatile和synchronized四個不同點
粒度不同: 後者針對物件和類,前者針對變數
syn阻塞: volatile執行緒不阻塞
syn保證三大特性:原子性,可見性,有序性。 而volatile只保證可見性,有序性。
syn編譯器優化,volatile不優化
H:多執行緒安全讀取一個域是三種方法: 1、利用鎖; 2、利用volatile域;3、final變數
三、 死鎖
死鎖是指兩個或兩個以上的程序在執行過程中,由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。