O 乛發表於2020-10-21

synchronized與java.util.concurrent.locks.Lock的相同和不同

相同點:Lock能完成synchronized所實現的所有功能。
不同點:Lock有比synchronized更精確的執行緒語義和更好的效能。
synchronized會自動釋放鎖,而Lock一點要求人工釋放,而且必須再finally語句中釋放。

Java中如何確保N個執行緒可以訪問N個資源,但同時又不導致死鎖

使用多執行緒的時候,一種非常簡單的避免死鎖的方式就是:指定獲取鎖的順序,並強制執行緒按照指定的順序獲取鎖。因此,如果所有的執行緒都是以同樣的順序加鎖和釋放鎖,就不會出現死鎖了
預防死鎖,預先破壞產生死鎖的四個條件。互斥不可能破壞。
1.破壞請求和保持條件,程式必須等所有要請求的資源都空閒時才能申請資源,這種方法會使資源嚴重浪費(有些資源可能僅在執行初期或結束時才使用,甚至根本不使用)。允許程式獲取初期所需資源後,便開始執行,執行過程中逐步釋放自己佔有的資源,比如有一個程式的任務時把資料複製到磁碟中再列印,前期只需獲得磁碟資源而不需要獲得印表機資源,待複製完畢後再釋放掉磁碟資源。這樣會使資源的利用率上升。
2.破壞不可搶佔條件,代價大,實現複雜。
3.破壞迴圈等待條件:對程式請求資源的順序做一個規定,避免相互等待。這種方法對資源的利用率比前兩種都高,但是前期要為裝置指定序號,新裝置加入會有一個問題,其次對使用者程式設計也有限制。

什麼是死鎖

兩個執行緒或兩個以上執行緒都在等待對方執行完畢才能繼續往下執行的時候就發生了死鎖。結果就是這些執行緒都陷入了無線的等待中。
例如,執行緒1鎖住了A,然後嘗試對B進行加鎖,同時執行緒2已經鎖住了B,接著嘗試對A進行加鎖,這時死鎖就發生了。執行緒1永遠得不到B,執行緒2永遠得不到執行緒A,並且它們永遠也不會知道發生了這樣的事情。為了得到彼此的物件,將永遠阻塞下去。這就是死鎖。

鎖和同步的區別

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

synchronized的可重入怎麼實現?

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

非公平鎖在reetranklock裡的實現過程是怎樣的

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

相關文章