ReenTrantLock 、synchronized 高併發性能測試

前言:

Synchronized 是依賴於JVM實現的,表現爲原生語法層面的互斥鎖。開發者是沒法直接看到相關源碼,可是咱們能夠經過利用javap工具查看生成的class文件信息來分析Synchronize的實現。同步代碼塊是使用monitorenter和monitorexit指令實現的,同步方法依靠的是方法修飾符上的ACC_SYNCHRONIZED實現。html

ReenTrantLock 是基於JDK實現的,一個表現爲API層面的互斥鎖,經過查閱源碼就能夠了解到。java

示例:

public class Lock1 {
    
    private static Lock lock = new ReentrantLock();
    
    private static int num1 = 0;
    private static int num2 = 0;
    public static void main(String[] args) {
        lockDemo();
        SyncDemo();
    }
    /** * 本機測試下20萬自增基本能肯定性能,可是不是特別明顯,50萬差距仍是挺大的 * 20萬如下數據synchronized優於Lock * 20萬以上數據Lock優於synchronized */
    public static void lockDemo(){
        long start = System.currentTimeMillis();
        for(int i=0;i<500000;i++){
            final int num = i;
            new Runnable() {
                @Override
                public void run() {
                    lock(num);
                }
            }.run();
        }
        long end = System.currentTimeMillis();
        System.out.println("累加:"+num1);
        System.out.println("ReentrantLock鎖:"+ (end-start));
    }
    public static void SyncDemo(){
        long start = System.currentTimeMillis();
        for(int i=0;i<500000;i++){
            final int num = i;
            new Runnable() {
                @Override
                public void run() {
                    sync(num);
                }
            }.run();
        }
        long end = System.currentTimeMillis();
        System.out.println("累加:"+num2);
        System.out.println("synchronized鎖:"+ (end-start));
    }
    public static void lock(int i){
        lock.lock();
        num1 ++;
        lock.unlock();
    }
    public static synchronized void sync(int i){
        num2 ++;
    }
}複製代碼

10萬++測試數據:api

累加:100000
ReentrantLock鎖:13
累加:100000
synchronized鎖:8複製代碼

50萬++測試數據:bash

累加:500000
ReentrantLock鎖:20
累加:500000
synchronized鎖:28複製代碼

看數據很明顯在高併發下,ReentrantLock 的性能是要優於 synchronized 的,雖然僅僅是幾毫秒的差距,固然這裏我並無對比CPU的使用狀況。併發

如何區分使用這兩種鎖?

可重入性oracle

ReenTrantLock 的字面意思就是再進入的鎖,synchronized關鍵字所使用的鎖也是可重入的,二者關於這個的區別不大。ide

功能區別高併發

Synchronized的使用比較方便,不須要開發者手動加鎖和釋放鎖,而ReenTrantLock須要手工聲明來加鎖和釋放鎖(lock() 和 unlock() 方法配合 try/finally 語句塊來實現)工具

ReenTrantLock 在鎖的細粒度和靈活度上要優於Synchronized。此外,還增長了一些高級特性,主要有如下3項:等待可中斷、可實現公平鎖以及鎖能夠綁定多個條件。性能

發展歷史

關於synchronized 與ReentrantLock
在JDK 1.6以後,虛擬機對於synchronized關鍵字進行總體優化後,在性能上synchronized與ReentrantLock已沒有明顯差距,所以在使用選擇上,須要根據場景而定,大部分狀況下咱們依然建議是synchronized關鍵字,緣由之一是使用方便語義清晰,二是性能上虛擬機已爲咱們自動優化。而ReentrantLock提供了多樣化的同步特性,如超時獲取鎖、能夠被中斷獲取鎖(synchronized的同步是不能中斷的)、等待喚醒機制的多個條件變量(Condition)等,所以當咱們確實須要使用到這些功能是,能夠選擇ReentrantLock。

更多可參考:www.javamadesoeasy.com/2015/03/dif…

相關文章
相關標籤/搜索