最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java并發(fā)編程Lock鎖可重入性與公平性分析

 更新時(shí)間:2022年05月13日 09:25:51   作者:字母哥  
這篇文章主要為大家介紹了java并發(fā)編程Lock鎖可重入性與公平性分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一、相似之處:Lock鎖 vs Synchronized 代碼塊

Lock鎖是一種類(lèi)似于synchronized 同步代碼塊的線程同步機(jī)制。從Java 5開(kāi)始java.util.concurrent.locks引入了若干個(gè)Lock鎖的實(shí)現(xiàn)類(lèi),所以通常情況下我們不需要實(shí)現(xiàn)自己的鎖,重要的是需要知道如何使用它們,了解它們實(shí)現(xiàn)背后的原理。

Lock鎖API的基本使用方法和Synchronized 關(guān)鍵字大同小異,代碼如下

Lock lock = new ReentrantLock();  //實(shí)例化鎖
//lock.lock(); //上鎖
boolean locked = lock.tryLock();  //嘗試上鎖
if(locked){
  try {
    //被鎖定的同步代碼塊,同時(shí)只能被一個(gè)線程執(zhí)行
  }finally {
    lock.unlock(); //放在finally代碼塊中,保證鎖一定會(huì)被釋放
  }
}
synchronized(obj){
    //被鎖定的同步代碼塊,同時(shí)只能被一個(gè)線程執(zhí)行
}

Lock鎖使用看上去麻煩一點(diǎn),但是java默認(rèn)提供了很多Lock鎖,能滿足更多的應(yīng)用場(chǎng)景。比如:基于信號(hào)量加鎖、讀寫(xiě)鎖等等,關(guān)注我的專(zhuān)欄《java并發(fā)編程》,后續(xù)都會(huì)介紹。

二、Lock接口中的方法

Lock接口實(shí)現(xiàn)方法通常會(huì)維護(hù)一個(gè)計(jì)數(shù)器,當(dāng)計(jì)數(shù)器=0的時(shí)候資源被釋放,當(dāng)計(jì)數(shù)器大于1的時(shí)候資源被鎖定。

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}
  • lock() - 調(diào)用該方法會(huì)使鎖定計(jì)數(shù)器增加1,如果此時(shí)共享資源是空閑的,則將鎖交給調(diào)用該方法的線程。
  • unlock() - 調(diào)用該方法使鎖定計(jì)數(shù)器減少1,當(dāng)鎖定計(jì)數(shù)器為0時(shí),資源被釋放。
  • tryLock() - 如果該資源是空閑的,那么調(diào)用該方法將返回true,鎖定計(jì)數(shù)器將增加1。如果資源處于被占用狀態(tài),那么該方法返回false,但是線程將不被阻塞。
  • tryLock(long timeout, TimeUnit unit) - 按照該方法嘗試獲得鎖,如果資源此時(shí)被占用,線程在退出前等待一定的時(shí)間段,該時(shí)間段由該方法的參數(shù)定義,以期望在此時(shí)間內(nèi)獲得資源鎖。
  • lockInterruptibly() - 如果資源是空閑的,該方法會(huì)獲取鎖,同時(shí)允許線程在獲取資源時(shí)被其他線程打斷。這意味著,如果當(dāng)前線程正在等待一個(gè)鎖,但其他線程要求獲得該鎖,那么當(dāng)前線程將被中斷,并立即返回不會(huì)獲得鎖。

三、不同點(diǎn):Lock鎖 vs Synchronized 代碼塊

使用synchronized同步塊和使用Lock API 之間還是有一些區(qū)別的

  • 一個(gè)synchronized同步塊必須完全包含在一個(gè)方法中 - 但Lock API的lock()和unlock()操作,可以在不同的方法中進(jìn)行
  • synchronized同步塊不支持公平性原則,任何線程都可以在釋放后重新獲得鎖,不能指定優(yōu)先級(jí)。但我們可以通過(guò)指定fairness 屬性在Lock API中實(shí)現(xiàn)公平的優(yōu)先級(jí),可以實(shí)現(xiàn)等待時(shí)間最長(zhǎng)的線程被賦予對(duì)鎖的占有權(quán)。
  • 如果一個(gè)線程無(wú)法訪問(wèn)synchronized同步塊,它就會(huì)被阻塞等待。Lock API提供了tryLock()方法,嘗試獲取鎖對(duì)象,獲取到鎖返回true,否則返回false。返回false并不阻塞線程,所以使用該方法可以減少等待鎖的線程的阻塞時(shí)間。

四、鎖的可重入性

”可重入“意味著某個(gè)線程可以安全地多次獲得同一個(gè)鎖對(duì)象,而不會(huì)造成死鎖。

4.1. synchronized鎖的可重入性

下面的代碼synchronized代碼塊嵌套synchronized代碼塊,鎖定同一個(gè)this對(duì)象,不會(huì)產(chǎn)生死鎖。證明synchronized代碼塊針對(duì)同一個(gè)對(duì)象加鎖,是可重入的。

public void testLock(){
    synchronized (this) {
      System.out.println("第1次獲取鎖,鎖對(duì)象是:" + this);
      int index = 1;
      do {
        synchronized (this) {
          System.out.println("第" + (++index) + "次獲取鎖,鎖對(duì)象是:" + this);
        }
      } while (index != 10);
    }
}

上面的這段代碼輸出結(jié)果是

第1次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116
第2次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116
第3次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116
第4次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116
第5次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116
第6次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116
第7次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116
第8次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116
第9次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116
第10次獲取鎖,鎖對(duì)象是:com.example.demo.thread.TestLockReentrant@769c9116

4.2.ReentrantLock可重入鎖

Lock接口的實(shí)現(xiàn)類(lèi)ReentrantLock,也是可重入鎖。一般來(lái)說(shuō)類(lèi)名包含Reentrant的Lock接口實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)的鎖都是可重入的。

public void testLock1(){
  Lock lock = new ReentrantLock();  //實(shí)例化鎖
  lock.lock();  //上鎖
  System.out.println("第1次獲取鎖,鎖對(duì)象是:" + lock);
  try {
    int index = 1;
    do {
      lock.lock();  //上鎖
      try {
        System.out.println("第" + (++index) + "次獲取鎖,鎖對(duì)象是:" + lock);
      }finally {
        lock.unlock();
      }
    } while (index != 10);
  }finally {
    lock.unlock(); //放在finally代碼塊中,保證鎖一定會(huì)被釋放
  }
}

當(dāng)線程第一次獲得鎖的時(shí)候,計(jì)數(shù)器被設(shè)置為1。在解鎖之前,該線程可以再次獲得鎖,每次計(jì)數(shù)器都會(huì)增加1。對(duì)于每一個(gè)解鎖操作,計(jì)數(shù)器被遞減1,當(dāng)計(jì)數(shù)器為0時(shí)鎖定資源被釋放。所以最重要的是:lock(tryLock)要與unlock方法成對(duì)出現(xiàn),即:在代碼中加鎖一次就必須解鎖一次,否則就死鎖

五、Lock鎖的公平性

Java的synchronized 同步塊對(duì)試圖進(jìn)入它們的線程,被授予訪問(wèn)權(quán)(占有權(quán))的優(yōu)先級(jí)順序沒(méi)有任何保證。因此如果許多線程不斷爭(zhēng)奪對(duì)同一個(gè)synchronized 同步塊的訪問(wèn)權(quán),就有可能有一個(gè)或多個(gè)線程從未被授予訪問(wèn)權(quán)。這就造成了所謂的 "線程饑餓"。為了避免這種情況,鎖應(yīng)該是公平的。

Lock lock = new ReentrantLock(true);

可重入鎖提供了一個(gè)公平性參數(shù)fairness ,通過(guò)該參數(shù)Lock鎖將遵守鎖請(qǐng)求的順序,即在一個(gè)線程解鎖資源后,鎖將被交給等待時(shí)間最長(zhǎng)的線程。這種公平模式是通過(guò)在鎖的構(gòu)造函數(shù)中傳遞 "true "來(lái)設(shè)置的。

以上就是java并發(fā)編程Lock鎖可重入性與公平性分析的詳細(xì)內(nèi)容,更多關(guān)于并發(fā)Lock鎖可重入性公平性的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 簡(jiǎn)單談?wù)凷pringMVC轉(zhuǎn)發(fā)和重定向的區(qū)別

    簡(jiǎn)單談?wù)凷pringMVC轉(zhuǎn)發(fā)和重定向的區(qū)別

    下面小編就為大家?guī)?lái)一篇簡(jiǎn)單談?wù)凷pringMVC轉(zhuǎn)發(fā)和重定向的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • 詳解jvm雙親委派機(jī)制

    詳解jvm雙親委派機(jī)制

    雙親委派機(jī)制保證了核心類(lèi)的安全,確保不會(huì)被修改,也保證了不會(huì)加載到重復(fù)的字節(jié)碼文件,這篇文章主要介紹了jvm雙親委派機(jī)制詳解,需要的朋友可以參考下
    2022-11-11
  • Java新手教程之ArrayList的基本使用

    Java新手教程之ArrayList的基本使用

    ArrayList就是傳說(shuō)中的動(dòng)態(tài)數(shù)組,用MSDN中的說(shuō)法,就是Array的復(fù)雜版本,這篇文章主要給大家介紹了關(guān)于Java新手教程之ArrayList基本使用的相關(guān)資料
    2021-06-06
  • Springmvc @PathVariable的用法解析

    Springmvc @PathVariable的用法解析

    這篇文章主要介紹了Springmvc @PathVariable的用法解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java中sharding-jdbc按年月分片的示例代碼

    Java中sharding-jdbc按年月分片的示例代碼

    本文主要介紹了Java中sharding-jdbc按年月分片的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Spring Boot集成SpringFox 3.0與Pageable參數(shù)處理方法

    Spring Boot集成SpringFox 3.0與Pageable參數(shù)處理方法

    這篇文章主要介紹了Spring Boot集成SpringFox 3.0與Pageable參數(shù)處理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-10-10
  • SpringMVC用XML方式實(shí)現(xiàn)AOP的方法示例

    SpringMVC用XML方式實(shí)現(xiàn)AOP的方法示例

    這篇文章主要介紹了SpringMVC用XML方式實(shí)現(xiàn)AOP的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • SpringBoot項(xiàng)目的漏洞修復(fù)經(jīng)驗(yàn)分享

    SpringBoot項(xiàng)目的漏洞修復(fù)經(jīng)驗(yàn)分享

    在局域網(wǎng)環(huán)境下,由于無(wú)法連接外網(wǎng)下載Maven包,常見(jiàn)解決方案是在外網(wǎng)環(huán)境搭建相同的開(kāi)發(fā)環(huán)境以便更新Maven包,本次漏洞掃描包括Tomcat、jackson-databind、fastjson、logback等組件,通常解決方法是升級(jí)到更高版本
    2024-10-10
  • Java實(shí)現(xiàn)的Base64加密算法示例

    Java實(shí)現(xiàn)的Base64加密算法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)的Base64加密算法,結(jié)合實(shí)例形式分析了Java實(shí)現(xiàn)的base64編碼轉(zhuǎn)換相關(guān)使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2018-04-04
  • 使用Logback設(shè)置property參數(shù)方式

    使用Logback設(shè)置property參數(shù)方式

    這篇文章主要介紹了使用Logback設(shè)置property參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03

最新評(píng)論

通州市| 金塔县| 岢岚县| 莱芜市| 家居| 句容市| 云浮市| 天柱县| 库车县| 乐安县| 东丰县| 北辰区| 靖江市| 阿图什市| 晋州市| 治多县| 柳林县| 当雄县| 城固县| 鄢陵县| 桐庐县| 香格里拉县| 钟山县| 安宁市| 徐闻县| 尼勒克县| 乐昌市| 淮北市| 伊宁市| 安达市| 梁平县| 武邑县| 宜宾市| 靖边县| 芷江| 广昌县| 龙泉市| 开封县| 汤阴县| 玉山县| 景德镇市|