日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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

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

文章目錄

  • 概述
  • 類圖結構
  • 主要方法
    • offer操作


概述

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


類圖結構

首先看一下LinkedBlockingQueue的類圖結構,以便從全局對LinkedBlockingQueue有個直觀的了解

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

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

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

/** 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();
  • 當調用線程在LinkedBlockingQueue實例上執行take、 poll等操作時需要獲取到takeLock鎖,從而保證同時只有一個線程可以操作鏈表頭節點。另外由于條件變量notEmpty內部的條件隊列的維護使用的是takeLock的鎖狀態管理機制,所以在調用notEmpty的await和signal方法前調用線程必須先獲取到takeLock鎖,否則會拋出IllegalMonitorStateException異常。notEmpty內部則維護著一個條件隊列,當線程獲取到takeLock鎖后調用notEmpty的await方法時,調用線程會被阻塞,然后該線程會被放到notEmpty內部的條件隊列進行等待,直到有線程調用了notEmpty的signal方法。

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

如下是LinkedBlockingQueue的無參構造函數的代碼。

/*** 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;// 初始化首 尾節點,并讓它指向哨兵節點last = head = new Node<E>(null);}

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


主要方法

offer操作

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。