java 遍历linkedblockingqueue_Java 并发编程 --- LinkedBlockingQueue与ArrayBlockingQueue (七)...

阻塞队列与普通的队列(LinkedList/ArrayList)相比,支持在向队列中添加元素时,队列的长度已满阻塞当前添加线程,直到队列未满或者等待超时;从队列中获取元素时,队列中元素为空 ,会将获取元素的线程阻塞,直到队列中存在元素 或者等待超时。

在JUC包中常用的阻塞队列包含ArrayBlockingQueue/LinkedBlockingQueue/LinkedBlockingDeque等,从结构来看都继承了AbstractQueue实现了BlockingQueue接口(LinkedBlockingDeque是双向阻塞队列,实现的是BlockingDeque接口),在BlockingQueue接口中定义了几个供子类实现的接口,可以分为3部分,puts操作、takes操作、其他操作。

puts操作

add(E e) : 添加成功返回true,失败抛IllegalStateException异常

offer(E e) : 成功返回true,如果此队列已满,则返回 false(如果添加了时间参数,且队列已满也会阻塞)

put(E e) :将元素插入此队列的尾部,如果该队列已满,则一直阻塞

takes操作

remove(Object o) :移除指定元素,成功返回true,失败返回false

poll() : 获取并移除此队列的头元素,若队列为空,则返回null(如果添加了时间参数,且队列中没有数据也会阻塞)

take():获取并移除此队列头元素,若没有元素则一直阻塞。

peek() :获取但不移除此队列的头;若队列为空,则返回null。

other操作

contains(Object o):队列中是否包含指定元素

drainTo(Collection super E> c):队列转化为集合

关于阻塞队列,我们主要看LinkedBlockingQueue与ArrayBlockingQueue.

ArrayBlockingQueue

ArrayBlockingQueue是基于数组的、有界的、遵循FIFO原则的阻塞队列,队列初始化时必须指定队列的长度。

这是一个经典的“有界缓冲区”,其中固定大小的数组包含由生产者插入并由消费者提取的元素。创建后,无法更改容量。此类支持用于排序等待生产者和消费者线程的可选公平策略。默认情况下,不保证此顺序。但是,将fairness设置为true构造的队列以FIFO顺序授予线程访问权限。公平性通常会降低吞吐量,但会降低可变性并避免饥饿。

结构

5c2fa3b5265faa04cb028bf6b6819b2c.png

相关变量

final Object[] items; //一个数组,用来存放队列中的变量(队列的基础)

int count; //队列中元素的数量

int takeIndex; //下一次take、poll、remove、peek操作的下标值

int putIndex; //下次add、offer、put操作的下标值

构造函数

ArrayBlockingQueue提供了三个构造函数,在只传递初始化大小值时,默认使用的锁是非公平锁,对比三个不同的构造函数而言,真正初始化队列的构造方法是ArrayBlockingQueue(int capacity, boolean fair)方法,传入集合的构造方法会在调用该方法后将集合遍历存入队列中

public ArrayBlockingQueue(intcapacity) {this(capacity, false);

}public ArrayBlockingQueue(intcapacity, boolean fair) {if (capacity <= 0)throw newIllegalArgumentException();this.items = newObject[capacity];lock = newReentrantLock(fair);//使用同一个锁对象,此处是与LinkedBlockingQueue(使用两个不同的锁来控制添加,取出操作)不同的地方

notEmpty = lock.newCondition();

notFull= lock.newCondition();

}public ArrayBlockingQueue(int capacity, boolean fair, Collection extends E>c) {this(capacity, fair);

final ReentrantLocklock = this.lock;lock.lock(); //Lock only for visibility, not mutual exclusion

try{int i = 0;try{for(E e : c) {

checkNotNull(e);//向数组中添加数据

items[i++] =e;

}

}catch(ArrayIndexOutOfBoundsException ex) {throw newIllegalArgumentException();

}

count=i;//设置下次添加操作对应的数组下标值

putIndex = (i == capacity) ? 0: i;

}finally{lock.unlock();

}

}

offer/add操作

add本质上调用的是offer操作,通过返回值true/false可以判断队列中添加元素是否成功,队列已满返回false

publicboolean offer(E e) {

checkNotNull(e);

final ReentrantLocklock = this.lock;lock.lock();try{//队列已满,直接返回false

if (count ==items.length)return false;else{

e

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值