Java面試題 鎖 synchronized BAT面試題系列 基礎篇(十一)


● 請你簡述一下synchronized與java.util.concurrent.locks.Lock的相同之處和不同之處?

考察點:鎖機制

參考回答:

主要相同點:Lock能完成synchronized所實現的所有功能
主要不同點:Lock有比synchronized更精確的線程語義和更好的性能。synchronized會自動釋放鎖,而Lock一定要求程序員手工釋放,並且必須在finally從句中釋放。

● JAVA中如何確保N個線程可以訪問N個資源,但同時又不導致死鎖? 

考察點:死鎖

參考回答:

使用多線程的時候,一種非常簡單的避免死鎖的方式就是:指定獲取鎖的順序,並強制線程按照指定的順序獲取鎖。因此,如果所有的線程都是以同樣的順序加鎖和釋放鎖,就不會出現死鎖了。

預防死鎖,預先破壞產生死鎖的四個條件。互斥不可能破壞,所以有如下三種方法:

1.破壞請求和保持條件,進程必須等所有要請求的資源都空閑時才能申請資源,這種方法會使資源浪費嚴重(有些資源可能僅在運行初期或結束時才使用,甚至根本不使用). 允許進程獲取初期所需資源后,便開始運行,運行過程中再逐步釋放自己占有的資源,比如有一個進程的任務是把數據復制到磁盤中再打印,前期只需獲得磁盤資源而不需要獲得打印機資源,待復制完畢后再釋放掉磁盤資源。這種方法比第一種方法好,會使資源利用率上升。

2.破壞不可搶占條件,這種方法代價大,實現復雜。

3.破壞循壞等待條件,對各進程請求資源的順序做一個規定,避免相互等待。這種方法對資源的利用率比前兩種都高,但是前期要為設備指定序號,新設備加入會有一個問題,其次對用戶編程也有限制。

● 請問什么是死鎖(deadlock)?

考察點:線程死鎖

參考回答:

兩個線程或兩個以上線程都在等待對方執行完畢才能繼續往下執行的時候就發生了死鎖。結果就是這些線程都陷入了無限的等待中。

例如,如果線程1鎖住了A,然后嘗試對B進行加鎖,同時線程2已經鎖住了B,接着嘗試對A進行加鎖,這時死鎖就發生了。線程1永遠得不到B,線程2也永遠得不到A,並且它們永遠也不會知道發生了這樣的事情。為了得到彼此的對象(A和B),它們將永遠阻塞下去。這種情況就是一個死鎖。

● 請說明一下鎖和同步的區別。

考察點:鎖

參考回答:

用法上的不同:
synchronized既可以加在方法上,也可以加載特定代碼塊上,而lock需要顯示地指定起始位置和終止位置。
synchronized是托管給JVM執行的,lock的鎖定是通過代碼實現的,它有比synchronized更精確的線程語義。
性能上的不同:
lock接口的實現類ReentrantLock,不僅具有和synchronized相同的並發性和內存語義,還多了超時的獲取鎖、定時鎖、等候和中斷鎖等。
在競爭不是很激烈的情況下,synchronized的性能優於ReentrantLock,競爭激烈的情況下synchronized的性能會下降的非常快,而ReentrantLock則基本不變。
鎖機制不同:
synchronized獲取鎖和釋放鎖的方式都是在塊結構中,當獲取多個鎖時,必須以相反的順序釋放,並且是自動解鎖。而Lock則需要開發人員手動釋放,並且必須在finally中釋放,否則會引起死鎖。

● 請說明一下synchronized的可重入怎么實現。

考察點:鎖

參考回答:

每個鎖關聯一個線程持有者和一個計數器。當計數器為0時表示該鎖沒有被任何線程持有,那么任何線程都都可能獲得該鎖而調用相應方法。當一個線程請求成功后,JVM會記下持有鎖的線程,並將計數器計為1。此時其他線程請求該鎖,則必須等待。而該持有鎖的線程如果再次請求這個鎖,就可以再次拿到這個鎖,同時計數器會遞增。當線程退出一個synchronized方法/塊時,計數器會遞減,如果計數器為0則釋放該鎖。

● 請講一下非公平鎖和公平鎖在reetrantlock里的實現過程是怎樣的。

考察點:鎖

參考回答:

如果一個鎖是公平的,那么鎖的獲取順序就應該符合請求的絕對時間順序,FIFO。對於非公平鎖,只要CAS設置同步狀態成功,則表示當前線程獲取了鎖,而公平鎖還需要判斷當前節點是否有前驅節點,如果有,則表示有線程比當前線程更早請求獲取鎖,因此需要等待前驅線程獲取並釋放鎖之后才能繼續獲取鎖。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM