天天看點

面試官:你都工作3年多了,怎麼連synchronize和Lock差別都沒掌握

作者:洪生鵬

作為一名程式員,在求職面試時,不知道你在求職面試時常會遇到關于線程的問題。

張工是一名java程式員,3年多工作經驗,有次到一家網際網路公司面試軟體開發工程師崗位,面試官就問了他這樣一個問題。

synchronized與Lock有什麼差別?

張工回答得不是很理想,面試官就說,你都工作3年多了,怎麼連synchronize和Lock差別都沒掌握。

聽面試官這麼一說,張工頓時不好意思,感覺這次面試估計要黃了。

對于這個問題,我在面試時我就曾遇到過,當時回答也不是很理想,今天簡單梳理下synchronized與Lock兩者之間有什麼差別。

我們知道,synchronized與Lock都是鎖,synchronized是java中的一個關鍵字,也就是說是Java語言内置的特性,那麼為什麼會出現Lock 鎖呢。兩者之間有什麼差別呢。

對于synchronized相信你并不陌生,我們時常會看到有一段代碼塊被synchronized修飾了,當一個線程擷取了對應的鎖,并執行該代碼塊時,其他線程便隻能一直等待,等待擷取鎖的線程釋放鎖。

這裡擷取鎖的線程釋放鎖會出現下面這兩種情況:

  1. 擷取鎖的線程執行完了該代碼塊,然後線程釋放對鎖的占有權;
  2. 線程執行發生異常,此時JVM會讓線程自動釋放鎖。

在這釋放鎖的過程彙總,要是擷取鎖的線程由于要等待IO被阻塞了,但是又沒有及時釋放鎖,那麼其他線程隻能一直等待,這樣就顯得很被動,對程式執行效率有很大的影響,使用者體驗會很差。

這時候Lock就派上用場了,Lock可以不讓等待的線程一直無期限地等待下去,比如在一定的時間就能夠做到響應中斷。

另外,從代碼層看,Lock是一個接口

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}           
面試官:你都工作3年多了,怎麼連synchronize和Lock差別都沒掌握

Lock

其中lock()、tryLock()、tryLock(long time, TimeUnit unit)和lockInterruptibly()方法是用來擷取鎖的。unLock()方法是用來釋放鎖的。

簡單來說,Lock和synchronized有什麼差別:

  • Lock是一個接口,而synchronized是Java中的關鍵字;
  • synchronized在發生異常時,會自動釋放線程占有的鎖,是以不會導緻死鎖現象發生;而Lock在發生異常時,如果沒有主動通過unLock()去釋放鎖,則很可能造成死鎖現象,需要注意的是,在使用Lock時需要在finally塊中釋放鎖;
  • Lock可以讓等待鎖的線程響應中斷,synchronized不行,使用synchronized時,等待的線程會一直等待下去,不能夠響應中斷;
  • 通過Lock可以知道有沒有成功擷取鎖,synchronized不行。

值得一提的是,Lock有ReadWriteLock支援并發讀。

讀寫鎖将對一個資源的通路分成了兩個鎖,一個ReadLock讀鎖和一個WriteLock寫鎖。正因為有了讀寫鎖,Lock才做到了多個線程之間的讀操作不會發生沖突。

面試官:你都工作3年多了,怎麼連synchronize和Lock差別都沒掌握

ReadWriteLock

面試官:你都工作3年多了,怎麼連synchronize和Lock差別都沒掌握

上面隻是對synchronized與Lock兩者差別簡單的對比,面試時,面試官問這樣的問題,synchronized與Lock有什麼差別,我想主要是考察求職者對線程并發基礎能力的掌握。

在實際應用中,線程以及線程安全性是非常重要,對于這部分内容了解不夠深入,而又需要用到生産項目中,遇到問題時很難定位到問題,容易造成損失。

對于一些常見的知識點,面試前建議多複習下。

由于筆者知識及水準有限,文中錯漏之處在所難免,如有不足之處,歡迎交流。

繼續閱讀