鎖的優化以及注意事項
阿新 • • 發佈:2018-10-31
1.減少鎖持有的時間。
只在有必要時進行同步。
2.減少鎖的粒度
分割資料結構
concurrentHashMap對應不同的區段segment進行加鎖,減少鎖鎖定的範圍。
concurrentHashMap 首先使用無鎖的方式求和。如果失敗了那麼就使用加鎖的方式求和。(先獲取所有的鎖,然後再求和,然後再釋放)
3.使用讀寫鎖替換獨佔鎖
4.鎖分離
如果將讀寫鎖的思想做進一步的延申,那就是鎖分離。
讀寫鎖是根據讀寫操作功能上的不同,進行了有效的鎖分離。
依據應用程式的功能特點,使用類似的分離思想,也可以對獨佔鎖進行分離。
比如LinkedBlockingQueue中,實現take()和pu(),分別實現的是從佇列中取得資料和增加資料的功能,雖然都是修改,但是兩個操作是分別位於佇列首端和佇列尾端,兩者並不衝突。
如果使用獨佔鎖,那麼要求兩個操作進行時獲取當前佇列的獨佔鎖,那麼take(),put()都沒辦法真正比能發。在執行的是,都會彼此等待對方釋放鎖資源。
因此在jdk中取而代之是的是兩把鎖,分類take(),put()操作定義了takeLock()和putLock(),那麼就可以同時寫了。
5.鎖粗化
虛擬機器在遇到一連串聯絡對同一鎖連續地對同一鎖不斷進行請求和釋放的操作,便會把所有的鎖操作整合成對鎖的一次請求,從而減少對鎖的請求同步次數,這個操作叫做鎖粗化。
類似這樣就沒有必要。
public void askLock(){ Integer length = 10; for (int i = 0; i < length; i++) { synchronized (this) { } } }
應該
public synchronized void askLock(){ Integer length = 10; for (int i = 0; i < length; i++) { } }
Java虛擬機器對鎖優化所做的努力
鎖偏向
好比你多次去一家店吃飯,吃得多了,老闆記住了你吃飯前每次洗筷子,吃飯後每次都要開發票,這樣的話,就是偏向你。
但是如果你每天都換飯店的話,那麼根本都沒有意義。
輕量級鎖
無鎖-輕量級鎖-重量級鎖
https://yq.aliyun.com/articles/49051