日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java Review - 并发编程_LinkedBlockingQueue原理源码剖析

發(fā)布時間:2025/3/21 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java Review - 并发编程_LinkedBlockingQueue原理源码剖析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 概述
  • 類圖結(jié)構(gòu)
  • 主要方法
    • offer操作


概述

Java Review - 并發(fā)編程_ConcurrentLinkedQueue原理&源碼剖析
介紹了使用CAS算法實現(xiàn)的非阻塞隊列ConcurrentLinkedQueue,下面我們來介紹使用獨占鎖實現(xiàn)的阻塞隊列LinkedBlockingQueue


類圖結(jié)構(gòu)

首先看一下LinkedBlockingQueue的類圖結(jié)構(gòu),以便從全局對LinkedBlockingQueue有個直觀的了解

  • 由類圖可以看到,LinkedBlockingQueue也是使用單向鏈表實現(xiàn)的,其也有兩個Node,分別用來存放首、尾節(jié)點,并且還有一個初始值為0的原子變量count,用來記錄隊列元素個數(shù)。

  • 另外還有兩個ReentrantLock的實例,分別用來控制元素入隊和出隊的原子性,其中takeLock用來控制同時只有一個線程可以從隊列頭獲取元素,其他線程必須等待,putLock控制同時只能有一個線程可以獲取鎖,在隊列尾部添加元素,其他線程必須等待

  • 另外,notEmpty和notFull是條件變量,它們內(nèi)部都有一個條件隊列用來存放進隊和出隊時被阻塞的線程,其實這是生產(chǎn)者—消費者模型

/** Current number of elements */private final AtomicInteger count = new AtomicInteger();/*** Head of linked list.* Invariant: head.item == null*/transient Node<E> head;/*** Tail of linked list.* Invariant: last.next == null*/private transient Node<E> last;/** Lock held by take, poll, etc */private final ReentrantLock takeLock = new ReentrantLock();/** Wait queue for waiting takes */private final Condition notEmpty = takeLock.newCondition();/** Lock held by put, offer, etc */private final ReentrantLock putLock = new ReentrantLock();/** Wait queue for waiting puts */private final Condition notFull = putLock.newCondition();
  • 當(dāng)調(diào)用線程在LinkedBlockingQueue實例上執(zhí)行take、 poll等操作時需要獲取到takeLock鎖,從而保證同時只有一個線程可以操作鏈表頭節(jié)點。另外由于條件變量notEmpty內(nèi)部的條件隊列的維護使用的是takeLock的鎖狀態(tài)管理機制,所以在調(diào)用notEmpty的await和signal方法前調(diào)用線程必須先獲取到takeLock鎖,否則會拋出IllegalMonitorStateException異常。notEmpty內(nèi)部則維護著一個條件隊列,當(dāng)線程獲取到takeLock鎖后調(diào)用notEmpty的await方法時,調(diào)用線程會被阻塞,然后該線程會被放到notEmpty內(nèi)部的條件隊列進行等待,直到有線程調(diào)用了notEmpty的signal方法。

  • 在LinkedBlockingQueue實例上執(zhí)行put、offer等操作時需要獲取到putLock鎖,從而保證同時只有一個線程可以操作鏈表尾節(jié)點。同樣由于條件變量notFull內(nèi)部的條件隊列的維護使用的是putLock的鎖狀態(tài)管理機制,所以在調(diào)用notFull的await和signal方法前調(diào)用線程必須先獲取到putLock鎖,否則會拋出IllegalMonitorStateException異常。notFull內(nèi)部則維護著一個條件隊列,當(dāng)線程獲取到putLock鎖后調(diào)用notFull的await方法時,調(diào)用線程會被阻塞,然后該線程會被放到notFull內(nèi)部的條件隊列進行等待,直到有線程調(diào)用了notFull的signal方法。

如下是LinkedBlockingQueue的無參構(gòu)造函數(shù)的代碼。

/*** A constant holding the maximum value an {@code int} can* have, 2<sup>31</sup>-1.*/@Native public static final int MAX_VALUE = 0x7fffffff;/*** Creates a {@code LinkedBlockingQueue} with a capacity of* {@link Integer#MAX_VALUE}.*/public LinkedBlockingQueue() {this(Integer.MAX_VALUE);}public LinkedBlockingQueue(int capacity) {if (capacity <= 0) throw new IllegalArgumentException();this.capacity = capacity;// 初始化首 尾節(jié)點,并讓它指向哨兵節(jié)點last = head = new Node<E>(null);}

由該代碼可知,默認(rèn)隊列容量為0x7fffffff,用戶也可以自己指定容量,所以從一定程度上可以說LinkedBlockingQueue是有界阻塞隊列。


主要方法

offer操作

總結(jié)

以上是生活随笔為你收集整理的Java Review - 并发编程_LinkedBlockingQueue原理源码剖析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。