一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Java源碼解析阻塞隊列ArrayBlockingQueue介紹

Java源碼解析阻塞隊列ArrayBlockingQueue介紹

2021-06-30 14:41李燦輝 Java教程

今天小編就為大家分享一篇關(guān)于Java源碼解析阻塞隊列ArrayBlockingQueue介紹,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

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

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

?
1
2
3
4
5
6
/** 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的初始化方法如下:

?
1
2
3
4
5
6
7
8
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方法。代碼如下。

?
1
2
3
4
5
6
7
8
9
10
11
12
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();
    }
  }

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

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

?
1
2
3
4
5
6
7
8
9
10
11
public e take() throws interruptedexception {
    final reentrantlock lock = this.lock;
    lock.lockinterruptibly();
    try {
      while (count == 0)
        notempty.await();
      return dequeue();
    } finally {
      lock.unlock();
    }
  }

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

分析代碼到這里的時候,我產(chǎn)生了一個疑問,如果當前隊列慢了,執(zhí)行put的線程在獲取到鎖之后,等待notfull條件上。那么,當執(zhí)行take操作的線程想獲取鎖時,阻塞隊列的鎖已經(jīng)被前面put的線程獲取了,那么take將永遠得不到機會執(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方法的作用上。因為condition是通過lock創(chuàng)建的,而調(diào)用condition的await方法時,會自動釋放和condition關(guān)聯(lián)的鎖。所以說,當put線程被阻塞后,它實際已經(jīng)釋放了鎖了。所以,當有take線程想執(zhí)行時,它是可以獲取到鎖的。

另一個問題:當?shù)却赾ondition上的線程被喚醒時,因為之前調(diào)用await前,已經(jī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.

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

總結(jié)

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

原文鏈接:https://blog.csdn.net/li_canhui/article/details/84100166

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 校园全黄h全肉细节文 | 亚洲人成网站在线观看青青 | 欧美男同互吃gay老头 | 欧美人交性视频在线香蕉 | 久久精品一卡二卡三卡四卡视频版 | 久久婷婷丁香五月色综合啪免费 | 四缺一写的小说 | 日你逼| 亚洲国产五月综合网 | 欧美粗黑巨大gay | 国产精品区牛牛影院 | xxxx成人 | 91亚洲成人| 青青草在视线频久久 | 欧美日韩亚洲国内综合网俺 | 成年人免费观看的视频 | 欧美日韩综合网在线观看 | 摸进老太婆的裤裆小说 | 国产精品馆 | α级毛片 | 全是女性放屁角色的手游 | 亚洲女性色尼古综合网 | 无人影院在线播放视频 | 国产免费小视频在线观看 | 欧美性黑人巨大gaysex | 色老板在线视频观看 | 美女操穴视频 | 四色6677最新永久网站 | 我的绝色岳每雯雯 | 免费国产一级观看完整版 | 四虎永久网址在线观看 | 精品一区二区三区色花堂 | 亚洲视频在线一区二区三区 | 护士videossexo另类 | 精品日韩欧美一区二区三区 | 好男人好资源在线观看 | 国产亚洲精品看片在线观看 | 亚洲入口| 国产裸舞在线一区二区 | 2020年精品国产午夜福利在线 | 爸爸的宝贝小说全文在线阅读 |