1. 程式人生 > >Java併發之鎖的優化

Java併發之鎖的優化

在高併發的環境下,激烈的鎖競爭會導致程式效能下降。

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. 使用無鎖函式