国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java鎖之重入鎖

Jinkey / 2412人閱讀

摘要:通過關鍵字可以實現多線程之間的同步控制,除了上述方法,為我們提供了很多并發控制的工具類,今天主要講的就是中的重入鎖,效果基本等同于關鍵字。

在講重入鎖之前,我們先看一段代碼

上述代碼想要實現的效果,就是使用兩個線程對i分別進行累加一百萬次,最終希望i的值是二百萬,如果按照上述代碼運行程序,你會發現i的值在絕大多數情況下都不能達到200萬,原因就是多線程的數據同步問題。
為了解決上述問題,我們自然而然想到synchronized關鍵字,通過對程序進行簡單改造,如下圖,紅框中的部分就是程序變動的部分:

在此處synchronized關鍵字的作用就是,當每個線程試圖對i進行++操作時,必須要先獲取o對象,一個o對象在同一時刻只能被一個線程所持有,其他線程必須要等待持有o對象的線程進行i++操作并且釋放o對象之后去試圖獲取o對象,如果獲取成功線程繼續執行,如果獲取失敗,線程繼續等待。通過synchronized關鍵字會使原本并行化的操作變成順序執行,也就是說同一時刻,只會有一個線程對i進行++,因此i最終的值必定會是200萬。

通過synchronized關鍵字可以實現多線程之間的同步控制,除了上述方法,Java為我們提供了很多并發控制的工具類,今天主要講的就是Java中的重入鎖ReentrantLock,效果基本等同于synchronized關鍵字。

使用重入鎖必須獲取一個重入鎖對象,通過new一個ReentrantLock即可獲得一個重入鎖對象。

使用重入鎖必須明確指定加鎖和解鎖操作,增強程序的可讀性。

同一把重入鎖只能在同一時刻只能被同一個線程鎖持有,也就是說,當線程1通過lock方法獲取鎖成功之后,其他線程如果想要獲得鎖必須等待線程1通過unlock方法釋放鎖之后才能獲取成功。

重入鎖支持多次加鎖和多次解鎖操作,但是加鎖和解鎖的次數必須保持一致,如果一個線程的加鎖次數大于解鎖次數,會使得當前線程一直占有這把重入鎖,其他線程永遠無法獲取鎖,從而產生饑餓現象,相反如果解鎖的次數大于加鎖次數,程序則會拋出IllegalMonitorStateException異常。

重入鎖提供中斷響應,就是在等待鎖的過程中可以取消對鎖的請求。

通過圖片上的代碼,很輕松的就構造了一個死鎖現象,當lock值是1,線程會先試圖獲取重入鎖lock1,500ms之后再試圖獲取重入鎖lock2,相反如果lock值不是1,線程會先試圖獲取重入鎖lock2,500ms之后在試圖獲取重入鎖lock1,此時,我在主函數中新開兩個線程,設置lock的值一個為1,另一個為2;

此時運行程序,你會發現程序永遠不會結束,原因就是兩個線程之間形成了死鎖現象。

細心的讀者或許已經發現,我在獲取重入鎖的時候不是使用lock()方法,而是使用的lockInterruptibly()方法,通過方法名稱也可以看出,lockInterruptibly()方法是支持中斷響應的。

下面我會在主線程通過t2.interrupt()中斷thread-2線程,這樣重入鎖2就會被釋放,從而使得thread-1可以正確執行完畢,但是thread-2只是被中斷,無法正確執行完畢,只會執行finally塊中的方法,最終程序的輸出結果如下圖:

除了通過中斷線程我們還可以通過鎖申請等待限時來避免死鎖和饑餓現象,所謂的鎖申請等待限時指的是申請鎖時指定一個最大等待時間,如果超過了等待時間還沒獲得鎖,線程就不再進行等待并且繼續執行。
獲取鎖時使用tryLock方法來獲取鎖就可以,此方法會有一個boolean返回值,如果獲取鎖成功,返回值為true,如果失敗,返回值即為false。該方法有兩個重載方法,如下圖:

上述的實現方式都是非公平鎖,所謂的非公平就是,線程獲取鎖的成功率是隨機的,有些鎖可能會一直成功獲取鎖,而有些線程會一直獲取不到鎖,而那些獲取不到鎖的線程就會一直處于等待狀態,從而產生饑餓現象。

為了解決上述問題,重入鎖支持多個線程之間以一種公平的方式來競爭獲取鎖,通俗一點講比如有兩個線程,兩個線程試圖獲取同一把鎖,假如說第一次成功獲取鎖的是線程1,那么下次成功獲取鎖的必定是線程2而不是線程1。

公平重入鎖的實現只需要在獲取重入鎖時,構造參數中指定true。

上述代碼通過主線程中新開兩個線程,每個線程所做的事就是循環的獲取fairLock這把重入鎖,由于fairLock是一把公平的重入鎖,因此t1和t2兩個線程會交替獲得鎖,程序運行效果圖如下圖:

雖然公平的重入鎖可以避免死鎖的現象,但因內部必須要維護一個有序的線程隊列,所以公平鎖的實現成本較高,性能相對低下。

最后附上上述實例代碼的地址:https://github.com/Meikoheng/...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70859.html

相關文章

  • Java中的鎖之樂觀鎖與悲觀鎖

    摘要:解決上問題在變量前添加版本號,將變成循環時間長開銷大,因為自旋需要消耗只能保證一個共享變量的原子操作分類二重入鎖支持重進入的鎖,排它鎖分類三讀寫鎖一對鎖,讀鎖,寫鎖,在同一時刻允許多線程訪問 1、 分類一:樂觀鎖與悲觀鎖   a)悲觀鎖:認為其他線程會干擾本身線程操作,所以加鎖 i.具體表現形式:synchronized關鍵字和lock實現類 ...

    huangjinnan 評論0 收藏0
  • 到底什么是入鎖,拜托,一次搞清楚!

    摘要:為什么叫重入鎖呢,我們把它拆開來看就明了了。釋放鎖,每次鎖持有者數量遞減,直到為止。 相信大家在工作或者面試過程中經常聽到重入鎖這個概念,或者與關鍵字 synchrozied 的對比,棧長面試了這么多人,80%的面試者都沒有答對或沒有答到點上,或者把雙重效驗鎖搞混了,哭笑不得。。 那么你對重入鎖了解有多少呢?今天,棧長幫大家撕開重入鎖的面紗,來見識下重入鎖的真實容顏。。 什么是重入鎖 ...

    LiuRhoRamen 評論0 收藏0
  • Java 中15種鎖的介紹:公平鎖,可入鎖,獨享鎖,互斥鎖,樂觀鎖,分段鎖,自旋鎖等等

    摘要:公平鎖非公平鎖公平鎖公平鎖是指多個線程按照申請鎖的順序來獲取鎖。加鎖后,任何其他試圖再次加鎖的線程會被阻塞,直到當前進程解鎖。重量級鎖會讓其他申請的線程進入阻塞,性能降低。 Java 中15種鎖的介紹 在讀很多并發文章中,會提及各種各樣鎖如公平鎖,樂觀鎖等等,這篇文章介紹各種鎖的分類。介紹的內容如下: 公平鎖 / 非公平鎖 可重入鎖 / 不可重入鎖 獨享鎖 / 共享鎖 互斥鎖 / 讀...

    LeoHsiun 評論0 收藏0
  • java入鎖、公平鎖和非公平鎖

    摘要:很吧判斷是否有前驅線程等待獲取鎖公平所和非公平鎖的各自優勢是什么那公平鎖很好理解,可以防止出現線程饑餓現象,每一個線程都有機會獲取到鎖。非公平鎖可能會導致線程饑餓,但是我們一般使用非公平鎖,因為非公平鎖可以減少上下文的切換,提高效率。 鎖的重入是指同一個線程可以多次獲取同一個鎖,synchronize是隱式的可重入鎖,ReentrantLock通過代碼實現了鎖的重入: fina...

    netmou 評論0 收藏0
  • Java多線程——入鎖ReentrantLock源碼閱讀

    摘要:所謂的重入,就是當本線程想再次獲得鎖,不需要重新申請,它本身就已經鎖了,即重入該鎖。如果不為,則表示有線程已經占有了。總結回顧下要點是一個可重入的鎖被當前占用的線程重入。 上一章《AQS源碼閱讀》講了AQS框架,這次講講它的應用類(注意不是子類實現,待會細講)。ReentrantLock,顧名思義重入鎖,但什么是重入,這個鎖到底是怎樣的,我們來看看類的注解說明showImg(http:...

    sushi 評論0 收藏0

發表評論

0條評論

Jinkey

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<