synchronized與ReentrantLock的區別

這是一個老生常談的問題,可是若是僅僅是那些比較廣泛的說法,我也不用記錄這篇文章,今天在寫二者代碼的時候還有一個不容易發現到的區別點。bash

常規區別

  • ReentrantLock更加靈活,提供了超時獲取鎖,可中斷鎖。提供了非公平鎖和非公平鎖,而synchronized僅僅是非公平鎖。
  • 用法上,ReentrantLock必須手動釋放鎖,而且只能修飾代碼塊。而synchronized不用手動釋放鎖,除此以外能夠修飾方法。

還有一個區別是使用synchronized的線程會被block住,而ReentrantLock的線程則是進入waiting狀態ide

疑問點

ReentrantLock真的比synchronized性能高嗎?性能

我寫了一個簡單的demo測試

public class LockDemo {

    static ReentrantLock lock = new ReentrantLock(false);

    public static void main(String[] args) {
        syncTest();
		 //分別測試
//        lockTest();
    }


    public static void syncTest() {
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    synchronized (lock) {
                        System.out.println(Thread.currentThread().getName() + "開始鎖定");
                        try {
                            Thread.sleep(2 * 1000);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            System.out.println(Thread.currentThread().getName() + "解鎖");

                        }
                    }
                }
            }.start();
        }
    }

    public static void lockTest() {
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + "開始鎖定");
                    try {
                        Thread.sleep(2 * 1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        System.out.println(Thread.currentThread().getName() + "解鎖");
                        lock.unlock();
                    }
                }
            }.start();
        }
    }

}

複製代碼

運行的結果以下:優化

Synchonized,其線程狀態只有time_waiting與blocked,當獲取到鎖的線程執行完畢以後,其他線程會一塊兒再次爭搶鎖spa

image-20190504181956547

image-20190504182035887

ReentrantLock的非公平鎖測試,儘管我用的是非公平鎖,可是看起來仍是有公平性的。其內部線程進入的是waiting狀態線程

image-20190504182246124

image-20190504182334411

至因而否性能是高點,我以爲單個線程去獲取鎖會比多個線程一塊兒去搶鎖性能會高一些吧,synchronized對鎖作的優化也只是在單線程以及兩個線程的時候作的優化,一旦升級爲重量級鎖,那些優化也就沒有效果了。code

固然這是我的猜想。cdn

最後

這裏其實看ReentrantLock內部的源碼能夠看到細節。blog

  • Locksupport.park,線程會進入waiting狀態
  • ReentrantLock儘管使用的是非公平鎖,可是若是有新的線程嘗試獲取到鎖的時候,只有當前的線程會去爭搶鎖。
相關文章
相關標籤/搜索