java併發編程之 Lock的優勢

本文導論:
JDK1.5 中新增了Lock接口及其一衆實現類,作者是大神 Doug Lea。Lock是一種在多線程環境下控制訪問共享資源的工具。在此之前,已經有關鍵字synchronized用於同步,那麼爲什麼還需要再造一個新的同步工具呢?Lock相比synchronized有什麼優勢?

總的來講,Lock提供了比synchronized更靈活更廣泛的鎖操作。爲什麼要出現Lock?其實就是搞清楚哪些場景是Lock能做而synchronized不能做,或者都能做但是Lock會更好。

  1. 獨佔。 synchronized只能提供對代碼塊/方法的獨佔訪問,ReadWriteLock可以支持讀併發。
  2. 獲取與釋放(順序、作用域、異常)
    • synchronized 以塊結構的形式獲取與釋放鎖。當獲取多個鎖時,他們必須以相反的順序被釋放。且鎖的獲取與釋放要在同一個詞法作用域中,退出塊結構自動釋放鎖。發生異常,自動釋放監視器鎖。
    • Lock 的實現類允許在不同的詞法作用域內以任意的順序獲取和釋放鎖,但是不會主動釋放鎖,需要在代碼中手動釋放。
 Lock l = ...;
 l.lock();
 try {
   // access the resource protected by this lock
 } finally {
   l.unlock();
 }
  1. 獲取鎖的花樣。Lock接口提供了比synchronized更多的功能。後者只能以阻塞的不可中斷的形式獲取鎖。

    • 以非阻塞的方式嘗試獲取鎖 tryLock()
    • 以可中斷的方式獲取鎖 lockInterruptibly()
    • 在有限時間內以可中斷的方式嘗試獲取鎖 tryLock(long,TimeUnit) throws InterruptedException
  2. 精細化
    Lock搭配Condition的 await() / single() / singleAll()可以實現更加精細化的操作,例如指定喚醒阻塞在某個condition的線程,這是synchronized搭配wait() / notify() / notifyall()做不到的。

  3. 公平性
    Lock可以支持公平鎖,也可以支持非公平鎖;synchronized只支持非公平鎖。
    公平鎖:鎖可獲取時,等待隊列中的第一個線程獲得鎖。
    非公平鎖:鎖可獲取時,所有等待線程一起競爭鎖。

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