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

Java源碼解析阻塞隊(duì)列ArrayBlockingQueue介紹

 更新時(shí)間:2019年01月09日 09:26:19   作者:李燦輝  
今天小編就為大家分享一篇關(guān)于Java源碼解析阻塞隊(duì)列ArrayBlockingQueue介紹,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧

Java的阻塞隊(duì)列,在實(shí)現(xiàn)時(shí),使用到了lock和condition,下面是對其主要方法的介紹。

首先看一下,阻塞隊(duì)列中使用到的鎖。

/** Main lock guarding all access **/
  final ReentrantLock lock;​
  /** Condition for waiting takes **/
  private final Condition notEmpty;​
  /** Condition for waiting puts **/
  private final Condition notFull;

主要的鎖是一個可重入鎖,根據(jù)注釋,它是用來保證所有訪問的同步。此外,還有2個condition,notEmpty用于take等待,notFull用于put等待。

兩個condition的初始化方法如下:

public ArrayBlockingQueue(int capacity, boolean fair) {
    if (capacity <= 0)
      throw new IllegalArgumentException();
    this.items = new Object[capacity];
    lock = new ReentrantLock(fair);
    notEmpty = lock.newCondition();
    notFull = lock.newCondition();
  }

下面介紹一下put方法。代碼如下。

public void put(E e) throws InterruptedException {
    checkNotNull(e);
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
      while (count == items.length)
        notFull.await();
      enqueue(e);
    } finally {
      lock.unlock();
    }
  }

進(jìn)行put時(shí),首先對待插入的元素進(jìn)行了非null判斷。然后獲取鎖。之后用一個循環(huán)進(jìn)行判斷,如果元素已滿,那么,就調(diào)用notFull的await方法,進(jìn)行阻塞。當(dāng)有別的線程(其實(shí)是take元素的線程)調(diào)用notFull的siginal方法后,put線程會被喚醒。喚醒后再確認(rèn)一下count是否小于items.length,如果是,則進(jìn)行加入隊(duì)列的操作。

下面介紹一下take方法,代碼如下:

public E take() throws InterruptedException {
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
      while (count == 0)
        notEmpty.await();
      return dequeue();
    } finally {
      lock.unlock();
    }
  }

進(jìn)行take時(shí),同樣先要獲取鎖,然后判斷元素個數(shù)是否為0,為0時(shí)需要等待在notEmpty條件上,等待被喚醒。喚醒之后,會再進(jìn)行一次元素個數(shù)判斷,然后進(jìn)行出隊(duì)列操作。

分析代碼到這里的時(shí)候,我產(chǎn)生了一個疑問,如果當(dāng)前隊(duì)列慢了,執(zhí)行put的線程在獲取到鎖之后,等待notFull條件上。那么,當(dāng)執(zhí)行take操作的線程想獲取鎖時(shí),阻塞隊(duì)列的鎖已經(jīng)被前面put的線程獲取了,那么take將永遠(yuǎn)得不到機(jī)會執(zhí)行。怎么回事呢?

后來,我查了condition的await方法,它的注釋如下:

  • Causes the current thread to wait until it is signalled or interrupted.
  • The lock associated with this Condition is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of four things happens......

原因在await方法的作用上。因?yàn)閏ondition是通過lock創(chuàng)建的,而調(diào)用condition的await方法時(shí),會自動釋放和condition關(guān)聯(lián)的鎖。所以說,當(dāng)put線程被阻塞后,它實(shí)際已經(jīng)釋放了鎖了。所以,當(dāng)有take線程想執(zhí)行時(shí),它是可以獲取到鎖的。

另一個問題:當(dāng)?shù)却赾ondition上的線程被喚醒時(shí),因?yàn)橹罢{(diào)用await前,已經(jīng)獲取了鎖,那么被喚醒時(shí),它是自動就擁有了鎖,還是需要重新獲取呢?

在await方法的注釋中,有如下的一段話:

  • In all cases, before this method can return the current thread must re-acquire the lock associated with this condition. When the thread returns it is guaranteed to hold this lock.

說明當(dāng)?shù)却赾ondition上的線程被喚醒時(shí),它需要重新獲取condition關(guān)聯(lián)的鎖,獲取到之后,await方法才會返回。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

  • 在?Spring?Boot?中使用?Quartz?調(diào)度作業(yè)的示例詳解

    在?Spring?Boot?中使用?Quartz?調(diào)度作業(yè)的示例詳解

    這篇文章主要介紹了在?Spring?Boot?中使用?Quartz?調(diào)度作業(yè)的示例詳解,在本文中,我們將看看如何使用Quartz框架來調(diào)度任務(wù),Quartz支持在特定時(shí)間運(yùn)行作業(yè)、重復(fù)作業(yè)執(zhí)行、將作業(yè)存儲在數(shù)據(jù)庫中以及Spring集成,需要的朋友可以參考下
    2022-07-07
  • 如何使用Java語言編寫打地鼠游戲全過程

    如何使用Java語言編寫打地鼠游戲全過程

    打地鼠是我們非常熟悉的一款小游戲,它的游戲結(jié)構(gòu)和規(guī)則也都比較簡單,那么如果能夠親自徒手開發(fā)這樣的一款經(jīng)典小游戲呢?這篇文章主要給大家介紹了關(guān)于如何使用Java語言編寫打地鼠游戲的相關(guān)資料,需要的朋友可以參考下
    2024-06-06
  • 使用spring配置文件.xml的頭文件

    使用spring配置文件.xml的頭文件

    這篇文章主要介紹了使用spring配置文件.xml的頭文件問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 一篇文章帶你入門Java數(shù)據(jù)類型

    一篇文章帶你入門Java數(shù)據(jù)類型

    下面小編就為大家?guī)硪黄狫ava的基本數(shù)據(jù)類型)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-08-08
  • nacos-discovery包名層級問題解決

    nacos-discovery包名層級問題解決

    這篇文章主要為大家介紹了nacos-discovery包名層級問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • 一文詳解SpringBoot如何使用pageHelper做分頁處理

    一文詳解SpringBoot如何使用pageHelper做分頁處理

    分頁是常見大型項(xiàng)目都需要的一個功能,PageHelper是一個非常流行的MyBatis分頁插件,下面就跟隨小編一起來了解下SpringBoot是如何使用pageHelper做分頁處理的吧
    2025-03-03
  • Hadoop1.2中配置偽分布式的實(shí)例

    Hadoop1.2中配置偽分布式的實(shí)例

    這篇文章主要介紹了Hadoop1.2中配置偽分布式的實(shí)例,使用的系統(tǒng)是linux mint 15 64bit,hadoop使用的是1.2.1版本,需要的朋友可以參考下
    2014-04-04
  • idea查看class字節(jié)碼的示例代碼

    idea查看class字節(jié)碼的示例代碼

    本文給大家分享三種方法介紹idea查看class字節(jié)碼,每種方法給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2025-04-04
  • Java Swing JLabel標(biāo)簽的使用方法

    Java Swing JLabel標(biāo)簽的使用方法

    這篇文章主要介紹了Java Swing JLabel標(biāo)簽的使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • java復(fù)制文件的4種方式及拷貝文件到另一個目錄下的實(shí)例代碼

    java復(fù)制文件的4種方式及拷貝文件到另一個目錄下的實(shí)例代碼

    這篇文章主要介紹了java復(fù)制文件的4種方式,通過實(shí)例帶給大家介紹了java 拷貝文件到另一個目錄下的方法,需要的朋友可以參考下
    2018-06-06

最新評論

乌兰浩特市| 利川市| 沈阳市| 云林县| 大理市| 山东| 澳门| 阿坝县| 轮台县| 沙湾县| 鄂州市| 阜平县| 井研县| 新余市| 杭锦旗| 固原市| 博罗县| 凉城县| 凯里市| 额尔古纳市| 康定县| 闵行区| 云龙县| 西丰县| 青神县| 临洮县| 大兴区| 宁城县| 漳州市| 来宾市| 改则县| 阿尔山市| 陆川县| 三江| 梨树县| 准格尔旗| 宜春市| 长葛市| 宜章县| 自治县| 乐至县|