ArrayBlockingQueue和LinkedBlockingQueue

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayBlockingQueue和LinkedBlockingQueue相关的知识,希望对你有一定的参考价值。

1. ArrayBlockingQueue 数组存储,固定大小的队列。

一个items数组,一个putIndex指针,从0到len代表已经入队了多少个元素。一个takeIndex指针,从0到len代表出队的元素位置。一个count,记录当前队列里有多少元素。

putIndex指针入队的时候不断++,takeIndex出队的时候不断++。这个队列不是一个循环队列,判断队列空和满用count和items.length比较。

 

入队:

内部的lock锁定,如果队列满,sleep等待,当可以插入的时候,items[++putIndex]是插入元素,如果队列插入以后满了,通知出队的等待线程。

lock.lock()

while(count == items.length)

  lock.condition.await() //释放锁,并等待

items[++putIndex] = element

count++

lock.condition.signal()

lock.unlock()

 

出队:

内部的lock锁定,如果队列空,sleep等待,当可以出队的时候,items[++takeIndex]

lock.lock()

while(count == 0)

  lock.condition.await() //释放锁,并等待

element = items[++takeIndex]

count--

lock.condition.signal()

lock.unlock()

 

2. LinkedBlockingQueue 链表存储,默认是无限制的队列

区别于ArrayBlockingQueue使用数组存储,在存储上是没有限制的,不过也可以通过capacity,count配合锁来控制队列长度。

head,last 代表链表的头尾指针,用来入队和出队,在last位置入队,head位置出队。

takeLock和putLock来控制队列空和满时候的阻塞,这里对比ArrayBlockingQueue,出队和入队使用的是两把锁。

capacity,count来控制队列中元素的数量,因为是用的两个锁,所以count是AtomicInteger。

 

入队:

putLock.lock()

while (count == capacity)

  putLock.condition.await()

last = last.next = element

count++

if (count + 1<capacity) //因为入队的时候有可能出队了,所以需要再检查一下,不像ArrayBlockingQueue直接signal()

  putLock.condition.signal()

putLock.unlock()

 

出队:

takeLock.lock()

while (count == 0)

  takeLock.condition.await()

element = head

head = element.next

count--

if (count > 1) 

  takeLock.condition.signal()

takeLock.unlock()

 

以上是关于ArrayBlockingQueue和LinkedBlockingQueue的主要内容,如果未能解决你的问题,请参考以下文章

JUC系列并发容器之阻塞队列Overview

并发队列之ArrayBlockingQueue

ArrayBlockingQueue和LinkedBlockingQueue

ArrayBlockingQueue和LinkedBlockingQueue

线程池的三种队列区别:SynchronousQueueLinkedBlockingQueue 和ArrayBlockingQueue

线程池的三种队列区别:SynchronousQueueLinkedBlockingQueue 和ArrayBlockingQueue