欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

首先看一下,阻塞隊(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;

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

兩個(gè)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í),首先對(duì)待插入的元素進(jìn)行了非null判斷。然后獲取鎖。之后用一個(gè)循環(huán)進(jìn)行判斷,如果元素已滿,那么,就調(diào)用notFull的await方法,進(jìn)行阻塞。當(dāng)有別的線程(其實(shí)是take元素的線程)調(diào)用notFull的siginal方法后,put線程會(huì)被喚醒。喚醒后再確認(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í),同樣先要獲取鎖,然后判斷元素個(gè)數(shù)是否為0,為0時(shí)需要等待在notEmpty條件上,等待被喚醒。喚醒之后,會(huì)再進(jìn)行一次元素個(gè)數(shù)判斷,然后進(jìn)行出隊(duì)列操作。

分析代碼到這里的時(shí)候,我產(chǎn)生了一個(gè)疑問,如果當(dāng)前隊(duì)列慢了,執(zhí)行put的線程在獲取到鎖之后,等待notFull條件上。那么,當(dāng)執(zhí)行take操作的線程想獲取鎖時(shí),阻塞隊(duì)列的鎖已經(jīng)被前面put的線程獲取了,那么take將永遠(yuǎn)得不到機(jī)會(huì)執(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í),會(huì)自動(dòng)釋放和condition關(guān)聯(lián)的鎖。所以說,當(dāng)put線程被阻塞后,它實(shí)際已經(jīng)釋放了鎖了。所以,當(dāng)有take線程想執(zhí)行時(shí),它是可以獲取到鎖的。

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

在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方法才會(huì)返回。

總結(jié)

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

相關(guān)文章

  • SpringCloud使用Zookeeper作為配置中心的示例

    SpringCloud使用Zookeeper作為配置中心的示例

    這篇文章主要介紹了SpringCloud使用Zookeeper作為配置中心的示例,幫助大家更好的理解和學(xué)習(xí)使用SpringCloud,感興趣的朋友可以了解下
    2021-04-04
  • Java網(wǎng)絡(luò)編程UDP實(shí)現(xiàn)消息發(fā)送及聊天

    Java網(wǎng)絡(luò)編程UDP實(shí)現(xiàn)消息發(fā)送及聊天

    這篇文章主要為大家詳細(xì)介紹了Java網(wǎng)絡(luò)編程UDP實(shí)現(xiàn)消息發(fā)送及聊天,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • java設(shè)計(jì)模式-代理模式(實(shí)例講解)

    java設(shè)計(jì)模式-代理模式(實(shí)例講解)

    下面小編就為大家?guī)硪黄猨ava設(shè)計(jì)模式-代理模式(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • Spring中的@Autowired、@Qualifier和@Primary注解詳解

    Spring中的@Autowired、@Qualifier和@Primary注解詳解

    這篇文章主要介紹了Spring中的@Autowired、@Qualifier和@Primary注解詳解,@Autowired?注解,可以對(duì)類成員變量、方法和構(gòu)造函數(shù)進(jìn)行標(biāo)注,完成自動(dòng)裝配的工作,@Autowired?是默認(rèn)根據(jù)?byType?進(jìn)行自動(dòng)裝配的,需要的朋友可以參考下
    2023-11-11
  • Spring boot通過HttpSessionListener監(jiān)聽器統(tǒng)計(jì)在線人數(shù)的實(shí)現(xiàn)代碼

    Spring boot通過HttpSessionListener監(jiān)聽器統(tǒng)計(jì)在線人數(shù)的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Spring boot通過HttpSessionListener監(jiān)聽器統(tǒng)計(jì)在線人數(shù)的實(shí)現(xiàn)代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • SpringBoot?HikariCP連接池詳解

    SpringBoot?HikariCP連接池詳解

    這篇文章主要介紹了SpringBoot2.0?中?HikariCP?數(shù)據(jù)庫(kù)連接池原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Spring數(shù)據(jù)庫(kù)多數(shù)據(jù)源路由配置過程圖解

    Spring數(shù)據(jù)庫(kù)多數(shù)據(jù)源路由配置過程圖解

    這篇文章主要介紹了Spring數(shù)據(jù)庫(kù)多數(shù)據(jù)源路由配置過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Java多線程 兩階段終止模式Two-Phase Termination Patter

    Java多線程 兩階段終止模式Two-Phase Termination Patter

    這篇文章主要介紹了Java多線程 兩階段終止模式Two-Phase Termination Patter,該模式有兩個(gè)角色,分別是Terminator,終止者,負(fù)責(zé)接收終止請(qǐng)求,執(zhí)行終止處理,處理完成后再終止自己。TerminationRequester終止請(qǐng)求發(fā)出者,用來向Terminator發(fā)出終止請(qǐng)求,需要的朋友可以參考一下
    2021-10-10
  • 淺談JAVA在項(xiàng)目中如何自定義異常

    淺談JAVA在項(xiàng)目中如何自定義異常

    今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識(shí),文章圍繞著JAVA在項(xiàng)目中如何自定義異常展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 詳解Java中類的加載順序

    詳解Java中類的加載順序

    Java中什么時(shí)候類加載,第一次需要使用類信息時(shí)加載。類加載的原則:延遲加載,能不加載就不加載。下面這篇文章主要介紹了Java中類的加載順序,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-01-01

最新評(píng)論