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()

时间: 2024-08-18 02:43:07

ArrayBlockingQueue和LinkedBlockingQueue的相关文章

ArrayBlockingQueue和LinkedBlockingQueue分析

一.BlockingQueue接口       BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会阻塞. 二.ArrayBlockingQueue      ArrayBlockingQueue是一个由数组支持的有界阻塞队列.在读写操作上都需要锁住整个容器,因此吞吐量与一般的实现是相似的,适合于实现“生产者消费者”模式. 三.LinkedBlock

BlockQueue中ArrayBlockingQueue和LinkedBlockingQueue比较

LinkedBlockingQueue是BlockingQueue的一种使用Link List的实现,它对头和尾(取和添加操作)采用两把不同的锁,相对于ArrayBlockingQueue提高了吞吐量.它也是一种阻塞型的容器,适合于实现"消费者生产者"模式. ArrayBlockingQueue是对BlockingQueue的一个数组实现,它使用一把全局的锁并行对queue的读写操作,同时使用两个Condition阻塞容量为空时的取操作和容量满时的写操作. 正因为LinkedBlock

JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue

目的:本文通过分析JDK源码来对比ArrayBlockingQueue 和LinkedBlockingQueue,以便日后灵活使用. 1. 在Java的Concurrent包中,添加了阻塞队列BlockingQueue,用于多线程编程.BlockingQueue的核心方法有: boolean add(E e) ,把 e 添加到BlockingQueue里.如果BlockingQueue可以容纳,则返回true,否则抛出异常. boolean offer(E e),表示如果可能的话,将 e 加到B

Java阻塞队列实现原理分析-ArrayBlockingQueue和LinkedBlockingQueue

Java中的阻塞队列接口BlockingQueue继承自Queue接口. BlockingQueue接口提供了3个添加元素方法. add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会抛出IllegalStateException异常 offer:添加元素到队列里,添加成功返回true,添加失败返回false put:添加元素到队列里,如果容量满了会阻塞直到容量不满 3个删除方法. poll:删除队列头部元素,如果队列为空,返回null.否则返回元素. remove:基于对象找到

ArrayBlockingQueue跟LinkedBlockingQueue的区别

.队列中的锁的实现不同 ArrayBlockingQueue中的锁是没有分离的,即生产和消费用的是同一个锁: LinkedBlockingQueue中的锁是分离的,即生产用的是putLock,消费是takeLock 2.在生产或消费时操作不同 ArrayBlockingQueue基于数组,在生产和消费的时候,是直接将枚举对象插入或移除的,不会产生或销毁任何额外的对象实例: LinkedBlockingQueue基于链表,在生产和消费的时候,需要把枚举对象转换为Node<E>进行插入或移除,会生

Java并发编程与技术内幕:ArrayBlockingQueue、LinkedBlockingQueue及SynchronousQueue源码解析

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了Java中BlockingQueue的源码 一.BlockingQueue介绍与常用方法 BlockingQueue是一个阻塞队列.在高并发场景是用得非常多的,在线程池中.如果运行线程数目大于核心线程数目时,也会尝试把新加入的线程放到一个BlockingQueue中去.队列的特性就是先进先出很容易理解,在java里头它的实现类主要有下图的几种,其中最常用到的是ArrayBl

20.并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解

1. ArrayBlockingQueue简介 在多线程编程过程中,为了业务解耦和架构设计,经常会使用并发容器用于存储多线程间的共享数据,这样不仅可以保证线程安全,还可以简化各个线程操作.例如在"生产者-消费者"问题中,会使用阻塞队列(BlockingQueue)作为数据容器,关于BlockingQueue可以看这篇文章.为了加深对阻塞队列的理解,唯一的方式是对其实验原理进行理解,这篇文章就主要来看看ArrayBlockingQueue和LinkedBlockingQueue的实现原理

深入剖析java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue

关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入理解Java并发之synchronized实现原理 Java并发编程-无锁CAS与Unsafe类及其并发包Atomic 深入理解Java内存模型(JMM)及volatile关键字 剖析基于并发AQS的重入锁(ReetrantLock)及其Condition实现原理 剖析基于并发AQS的共

java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue

Java中阻塞队列接口BlockingQueue继承自Queue接口,并提供put.take阻塞方法.两个主要的阻塞类实现是ArrayBlockingQueue和LinkedBlockingQueue.阻塞队列的主要方法 public interface BlockingQueue<E> extends Queue<E> { //将指定的元素插入到此队列的尾部(如果立即可行且不会超过该队列的容量) //在成功时返回 true,如果此队列已满,则抛IllegalStateExcept