【多執行緒】執行緒同步 synchronized
阿新 • • 發佈:2022-04-01
由於同一程序的多個執行緒共享同一塊儲存空間 , 在帶來方便的同時,也帶來了訪問 衝突問題 , 為了保證資料在方法中被訪問時的正確性 , 在訪問時加入 鎖機制synchronized , 當一個執行緒獲得物件的排它鎖 , 獨佔資源 , 其他執行緒必須等待 , 使用後釋放鎖即可 . 存在以下問題 :
- 一個執行緒持有鎖會導致其他所有需要此鎖的執行緒掛起 ;
- 在多執行緒競爭下 , 加鎖 , 釋放鎖會導致比較多的上下文切換 和 排程延時,引 起效能問題 ;
- 如果一個優先順序高的執行緒等待一個優先順序低的執行緒釋放鎖 會導致優先順序倒 置 , 引起效能問題 。
同步方法
由於我們可以通過 private 關鍵字來保證資料物件只能被方法訪問 , 所以我們只需 要針對方法提出一套機制 , 這套機制就是 synchronized 關鍵字 , 它包括兩種用法 synchronize方法
和synchronized 塊 。
//同步方法
public synchronized void method(int args){}
synchronized方法控制對 “物件” 的訪問 , 每個物件對應一把鎖 , 每個 synchronized方法都必須獲得呼叫該方法的物件的鎖才能執行 , 否則執行緒會阻塞 , 方法一旦執行 , 就獨佔該鎖 , 直到該方法返回才釋放鎖 , 後面被阻塞的執行緒才能獲 得這個鎖 , 繼續執行。
-
若將一個大的方法申明為synchronized 將會影響效率。
-
方法裡面需要修改的內容才需要鎖, 鎖的太多 ,浪費資源。
同步塊
//同步塊 synchronized (Obj){}
-
Obj 稱之為 同步監視器
-
Obj 可以是任何物件 , 但是推薦使用共享資源作為同步監視器
-
同步方法中無需指定同步監視器 , 因為同步方法的同步監視器就是this , 就是 這個物件本身 , 或者是 class
-
-
同步監視器的執行過程
- 第一個執行緒訪問 , 鎖定同步監視器 , 執行其中程式碼 。
- 第二個執行緒訪問 , 發現同步監視器被鎖定 , 無法訪問 。
- 第一個執行緒訪問完畢 , 解鎖同步監視器 。
- 第二個執行緒訪問, 發現同步監視器沒有鎖 , 然後鎖定並訪。