ReentrantLock和內部鎖的性能對比【轉】

 ReentrantLock是jdk5引入的新的鎖機制,它與內部鎖(synchronize) 相同的併發性和內存語義,比如可重入加鎖語義。在中等或者更高負荷下,ReentrantLock有更好的性能,並且擁有可輪詢和可定時的請求鎖等高級功能。這個程序簡單對比了ReentrantLock公平鎖、ReentrantLock非公平鎖以及內部鎖的性能,從結果上看,非公平的ReentrantLock表現最好。內部鎖也僅僅是實現統計意義上的公平,結果也比公平的ReentrantLock好上很多。這個程序僅僅是計數,啓動N個線程,對同一個Counter進行遞增,顯然,這個遞增操作需要同步以保證原子性,採用不同的鎖來實現同步,然後查看結果。
Counter接口:

package net.rubyeye.concurrency.chapter13;

public interface Counter {
    
public long getValue();

    
public void increment();

}


然後,首先使用我們熟悉的synchronize來實現同步:

package net.rubyeye.concurrency.chapter13;

public class SynchronizeBenchmark implements Counter {
    
private long count = 0;

    
public long getValue() {
        
return count;
    }

    
public synchronized void increment() {
        count
++;
    }
}


採用ReentrantLock的版本,切記要在finally中釋放鎖,這是與synchronize使用方式最大的不同,內部鎖jvm會自動幫你釋放鎖,而ReentrantLock需要你自己來處理。

package net.rubyeye.concurrency.chapter13;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockBeanchmark implements Counter {

    
private volatile long count = 0;

    
private Lock lock;

    
public ReentrantLockBeanchmark() {
        
// 使用非公平鎖,true就是公平鎖
        lock = new ReentrantLock(false);
    }

    
public long getValue() {
        
// TODO Auto-generated method stub
        return count;
    }

    
public void increment() {
        lock.lock();
        
try {
            count
++;
        } 
finally {
            lock.unlock();
        }
    }

}


    寫一個測試程序,使用CyclicBarrier來等待所有任務線程創建完畢以及所有任務線程計算完成,清單如下:

package net.rubyeye.concurrency.chapter13;

import java.util.concurrent.CyclicBarrier;

public class BenchmarkTest {
    
private Counter counter;

    
private CyclicBarrier barrier;

    
private int threadNum;

    
public BenchmarkTest(Counter counter, int threadNum) {
        
this.counter = counter;
        barrier 
= new CyclicBarrier(threadNum + 1); //關卡計數=線程數+1
        this.threadNum = threadNum;
    }

    
public static void main(String args[]) {
        
new BenchmarkTest(new SynchronizeBenchmark(), 5000).test();
        
//new BenchmarkTest(new ReentrantLockBeanchmark(), 5000).test();
        //new BenchmarkTest(new ReentrantLockBeanchmark(), 5000).test();   
    }

    
public void test() {
        
try {
            
for (int i = 0; i < threadNum; i++) {
                
new TestThread(counter).start();
            }
            
long start = System.currentTimeMillis();
            barrier.await(); // 等待所有任務線程創建
            barrier.await(); // 等待所有任務計算完成
            long end = System.currentTimeMillis();
            System.out.println(
"count value:" + counter.getValue());
            System.out.println(
"花費時間:" + (end - start) + "毫秒");
        } 
catch (Exception e) {
            
throw new RuntimeException(e);
        }
    }

    
class TestThread extends Thread {
        
private Counter counter;

        
public TestThread(final Counter counter) {
            
this.counter = counter;
        }

        
public void run() {
            
try {
                barrier.await();
                
for (int i = 0; i < 100; i++)
                    counter.increment();
                barrier.await();
            } 
catch (Exception e) {
                
throw new RuntimeException(e);
            }
        }
    }
}

 


分別測試一下,

將啓動的線程數限定爲500,結果爲:
公平ReentrantLock:      210 毫秒
非公平ReentrantLock :   39  毫秒
內部鎖:                          39 毫秒

將啓動的線程數限定爲1000,結果爲:
公平ReentrantLock:      640 毫秒
非公平ReentrantLock :   81 毫秒
內部鎖:                           60 毫秒

線程數不變,test方法中的循環增加到1000次,結果爲:
公平ReentrantLock:      16715 毫秒
非公平ReentrantLock :   168 毫秒
內部鎖:                           639  毫秒

將啓動的線程數增加到2000,結果爲:
公平ReentrantLock:      1100 毫秒
非公平ReentrantLock:   125 毫秒
內部鎖:                           130 毫秒

將啓動的線程數增加到3000,結果爲:
公平ReentrantLock:      2461 毫秒
非公平ReentrantLock:   254 毫秒
內部鎖:                           307 毫秒

啓動5000個線程,結果如下:
公平ReentrantLock:      6154  毫秒
非公平ReentrantLock:   623   毫秒
內部鎖:                           720 毫秒

 

非公平ReentrantLock和內部鎖的差距,在jdk6上應該縮小了,據說jdk6的內部鎖機制進行了調整

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章