鎖效能優化的幾種思路
一、減少執行緒持有鎖的時間
一個方法中,並不是所有的地方都需要同步。所以,只在需要同步的地方,進行加鎖操作。
在程式碼中,可以把同步方法修改為同步程式碼塊,可以減少執行緒持有鎖的時間,從而提高效能。
public synchronized void synMethod() {
methodA();//不需要同步的A方法
methodB();//需要同步的B方法
methodC();//不需要同步的C方法
}
public void synMethod() { methodA(); //不需要同步的A方法 synchronized (this) { methodB(); //需要同步的B方法 } methodC(); //不需要同步的C方法 }
二、減少鎖粒度:鎖分段技術
將一個物件的資料分割成多個部分,併為每個部分分配一把鎖。
我們通常使用HashMap的時候,為了能夠保證HashMap的同步性,會使用Collections.synchroinzedMap(map)方法返回一個同步的HashMap。而操作這個HashMap的讀執行緒與寫執行緒會相互阻塞,所以同一時刻只能有一個執行緒在操作。
在ConcurrentHashMap的源中,我們可以發現,它把整個HashMap拆成了若干個小的segment,每一個segment都是一個小的HashMap。每一個小的HashMap分配一把鎖。當一個執行緒進入了一個小的HashMap,另外的執行緒可以進入其它的小的HashMap。這樣,同一時刻,能讓多個執行緒同時操作
三、操作互不影響:鎖分離技術
只要操作相不影響,鎖就可以分離。比如一個佇列,從佇列頭讀取資料,從佇列尾寫入資料,理論上說他們是不衝突的,也就是說是可以鎖分離的。除非佇列只有一個數據。鎖分離在java中應用延伸的一個例子就是LinkedBlockingQueue。
另外一個鎖分離的應用就是 讀寫鎖ReentranceReadWriteLock,讀讀互不影響,可以同時有多個執行緒讀取資料。
四、其它
還有鎖粗化和鎖消除。
鎖粗化就是把執行時間非常短的方法直接加入到同步方法中
鎖消除就是消除掉 JDK 程式碼中自帶的鎖,比如消除掉StringBuffer中的同步鎖。
.