本文導論:
JDK1.5 中新增了Lock接口及其一衆實現類,作者是大神 Doug Lea。Lock是一種在多線程環境下控制訪問共享資源的工具。在此之前,已經有關鍵字synchronized用於同步,那麼爲什麼還需要再造一個新的同步工具呢?Lock相比synchronized有什麼優勢?
總的來講,Lock提供了比synchronized更靈活更廣泛的鎖操作。爲什麼要出現Lock?其實就是搞清楚哪些場景是Lock能做而synchronized不能做,或者都能做但是Lock會更好。
- 獨佔。 synchronized只能提供對代碼塊/方法的獨佔訪問,ReadWriteLock可以支持讀併發。
- 獲取與釋放(順序、作用域、異常)
- synchronized 以塊結構的形式獲取與釋放鎖。當獲取多個鎖時,他們必須以相反的順序被釋放。且鎖的獲取與釋放要在同一個詞法作用域中,退出塊結構自動釋放鎖。發生異常,自動釋放監視器鎖。
- Lock 的實現類允許在不同的詞法作用域內以任意的順序獲取和釋放鎖,但是不會主動釋放鎖,需要在代碼中手動釋放。
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
-
獲取鎖的花樣。Lock接口提供了比synchronized更多的功能。後者只能以阻塞的不可中斷的形式獲取鎖。
- 以非阻塞的方式嘗試獲取鎖 tryLock()
- 以可中斷的方式獲取鎖 lockInterruptibly()
- 在有限時間內以可中斷的方式嘗試獲取鎖 tryLock(long,TimeUnit) throws InterruptedException
-
精細化
Lock搭配Condition的 await() / single() / singleAll()可以實現更加精細化的操作,例如指定喚醒阻塞在某個condition的線程,這是synchronized搭配wait() / notify() / notifyall()做不到的。 -
公平性
Lock可以支持公平鎖,也可以支持非公平鎖;synchronized只支持非公平鎖。
公平鎖:鎖可獲取時,等待隊列中的第一個線程獲得鎖。
非公平鎖:鎖可獲取時,所有等待線程一起競爭鎖。