Java多線程之ReentrantLock基礎篇

synchronized原理可以參考此篇文章

ReentrantLock與synchronized的比較

  • 共同點
    • 二者都屬於可重入鎖、獨佔鎖(即不同線程之間的訪問是互斥的)
  • 不同點
    • synchronized加鎖與解鎖是隱試的ReentrantLock是顯示的
    • synchronized不可響應中斷,一個線程獲取不到鎖就一直等着,ReentrantLock可以相應中斷(使用lockInterruptibly()方法加鎖)
    • synchronized是非公平鎖,ReentrantLock可以通過過程函數傳入參數指定鎖是否是公平鎖,所謂公平鎖就是誰等待時間長誰先獲取鎖,非公平鎖就線程之間自由競爭隨機佔用鎖
    • ReentrantLock有嘗試獲取鎖的方法tryLock()
      • 鎖處於空閒:返回true,將鎖持有者設置爲1
      • 當前線程持有鎖(可重入鎖):返回true,同時將鎖持有者加1
      • 其他線程持有鎖:返回false
public class MyReentrantLock {
    private static ReentrantLock lock1 = new ReentrantLock();

    private static ReentrantLock lock2 = new ReentrantLock();

    public static void main(String[] args) {
        new Thread(()->{
            lock1.lock();
        },"Thread-1").start();

        new Thread(()->{
            /*由於Thread-1未釋放鎖lock1,因此b=false*/
            boolean b = lock1.tryLock();
            System.out.println(b);
        },"Thread-2").start();


        new Thread(()->{
            /*
            *由於鎖lock2被當前線程持有,
            *因此當前線程調用tryLock()嘗試獲取鎖,是能夠得到鎖的
            * */
            lock2.lock();
            boolean b = lock2.tryLock();
            System.out.println(b);
        },"Thread-3").start();
    }
}

關於ReentrantLock需要注意的點

  • 釋放鎖的操作務必放在finally代碼塊裏
  • 由於ReentrantLock是可重入鎖,因此要特別注意加鎖與釋放鎖的次數要一直
public class MyReentrantLock {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock(true);
        lock.lock();
        try {
            // 此處省略功能代碼
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章