Java併發之鎖的優化
阿新 • • 發佈:2019-01-26
在高併發的環境下,激烈的鎖競爭會導致程式效能下降。
1、減小鎖持有的時間
在鎖的競爭過程中,如果某個執行緒獲得了鎖,那其他執行緒就只有等了,如果該執行緒持有的時間長,那就會影響系統性能。
public void synchronized function(){
otherCode1();
mutexCode(); //需要同步的程式碼
otherCode2();
}
//改為
public void function(){
otherCode1();
synchronized {
mutexCode();
}
otherCode2();
}
2、鎖粗化
在程式中,應該避免對同一個鎖不停地請求,同步和釋放。這本身也會消耗系統寶貴的資源,不利於效能優化。
for(int i=0; i<max; i++) {
synchronized(lock) {
}
}
//改成
synchronized(lock) {
for(int i=0; i<max; i++) {
}
}
public void fun() {
synchronized(lock) {
}
//其他不需要同步的工作,但可以很快執行完
synchronized(lock) {
}
}
//改成
public void fun() {
//整合成一個鎖
synchronized(lock) {
}
}
3、避免死鎖
巢狀使用鎖是死鎖最主要的原因,類似下面的情況,要麼是在一個方法類,要麼在多個方法中相互呼叫。
public void fun1() {
synchronized (obj1) {
synchronized (obj2) {
}
}
}
public void fun2() {
synchronized (obj2) {
synchronized (obj1) {
}
}
}
1. 按順序加鎖
2. 使用定時鎖
ReentrantLock. tryLock(long time, TimeUnit unit):在給定時間內嘗試獲取鎖
3. 使用Semaphore
Semaphore可以控制某個資源可被同時訪問的個數,通過 acquire() 獲取一個許可,如果沒有就等待,而 release() 釋放一個許可。
4. 避免一個執行緒在鎖內同時佔用多個資源,儘量保證每個鎖只佔用一個資源
5. 使用無鎖函式