日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java锁优化

發布時間:2025/4/5 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java锁优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java鎖優化

應用程序在并發環境下會產生很多問題,通常情況下,我們可以通過加鎖來解決多線程對臨界資源的訪問問題。但是加鎖往往會成為系統的瓶頸,因為加鎖和釋放鎖會涉及到與操作系統的交互,會有很大的性能問題。那么這個時候基于鎖的優化手段就顯得很重要了。

一般情況下,可以從兩個角度進行鎖優化:對單個鎖算法的優化和對鎖粒度的細分。

1. 單個鎖的優化

自旋鎖:

? 非自旋鎖在未獲取鎖的情況會被阻塞,之后再喚醒嘗試獲得鎖。而JDK的阻塞和喚醒是基于操作系統實現的,會有系統資源的開銷。自旋鎖就是線程不停地循環嘗試獲得鎖,而不會將自己阻塞,這樣不會浪費系統的資源開銷,但是會浪費CPU的資源。所有現在的JDK大部分都是先自旋等待,如果自旋等待一段時間之后還沒有獲取到鎖,就會將當前線程阻塞。

鎖消除:

? 當JVM分析代碼時發現某個方法只被單個線程安全訪問,而且這個方法是同步方法,那么JVM就會去掉這個方法的鎖。

單個鎖優化的瓶頸:

? 對單個鎖優化的效果就像提高單個CPU的處理能力一樣,最終會由于各個方面的限制而達到一個平衡點,到達這個點之后優化單個鎖的對高并發下面鎖的優化效果越來越低。所以將一個鎖進行粒度細分帶來的效果會很明顯,如果一個鎖保護的代碼塊被拆分成兩個鎖來保護,那么程序的效率就大約能夠提高到2倍,這個比單個鎖的優化帶來的效果要明顯很多。常見的鎖粒度細分技術有:鎖分解和鎖分段

2. 細分鎖粒度

細分鎖粒度的目的是降低競爭鎖的概率。

2.1 鎖分解

鎖分解的核心是將無關的代碼塊,如果在一個方法中有一部分的代碼與鎖無關,一部分的代碼與鎖有關,那么可以縮小這個鎖的返回,這樣鎖操作的代碼塊就會減少,鎖競爭的可能性也會減少

縮小鎖的范圍

縮小鎖的范圍是指盡量只在必要的地方加鎖,不要擴大加鎖的范圍,就拿單例模式舉例,范圍大的鎖可能將整個方法都加鎖了:

class Singleton {private Singleton instance;private Singleton() {}// 將整個方法加鎖public synchronized Singleton getInstance() {try {Thread.sleep(1000); //do somethingif(null == instance)instance = new Singleton();} catch (InterruptedException e) {e.printStackTrace();}return instance;}}

優化后的,只將部分代碼加鎖:

class Singleton {private Singleton instance;private Singleton() {}public Singleton getInstance() {try {Thread.sleep(1000); //do something// 只對部分代碼加鎖synchronized(this) {if(null == instance)instance = new Singleton();}} catch (InterruptedException e) {e.printStackTrace();}return instance;} }

減少鎖的粒度

減少鎖的粒度是指如果一個鎖需要保護多個相互獨立的變量,那么可以將一個鎖分解為多個鎖,并且每個鎖保護一個變量,這樣就可以減少鎖沖突。看一下下面的例子:

class Demo{private Set<String> allUsers = new HashSet<String>();private Set<String> allComputers = new HashSet<String>();//公用一把鎖public synchronized void addUser(String user){ allUsers.add(user);}public synchronized void addComputer(String computer){allComputers.add(computer);} }

縮小鎖的粒度后,將一個鎖拆分為多個:

class Demo{private Set<String> allUsers = new HashSet<String>();private Set<String> allComputers = new HashSet<String>();//分解為兩把鎖public void addUser(String user){ synchronized (allUsers){allUsers.add(user);}}public void addComputer(String computer){synchronized (allComputers){allComputers.add(computer);}} }

如上的方法把一個鎖分解為2個鎖時候,采用兩個線程時候,大約能夠使程序的效率提升一倍。

2.2 鎖分段

鎖分段和縮小鎖的粒度類似,就是將鎖細分的粒度更多,比如將一個數組的每個位置當做單獨的鎖。JDK8以前ConcurrentHashMap就使用了鎖分段技術,它將散列數組分成多個Segment,每個Segment存儲了實際的數據,訪問數據的時候只需要對數據所在的Segment加鎖就行。

總結

以上是生活随笔為你收集整理的Java锁优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。