Java里的阻塞队列
JDK7提供了7个阻塞队列,如下:
ArrayBlockingQueue : 一个数组结构组成的有界阻塞队列。
LinkedBlockingQueue : 一个由链表结构组成的有界阻塞队列 。
PriorityBlockingQueue : 一个支持优先级排序的无界阻塞队列 。
DelayQueue : 一个使用优先级队列实现的无界阻塞队列 。
SynchronousQueue : 一个不存储元素的阻塞队列 。
LinkedTransferQueue : 一个由链表结构组成的无界阻塞队列 。
LinkedBlockingDeque : 一个由链表结构组成的双向阻塞队列 。
下面分别介绍几个队列 :
1.ArrayBlockingQueue
ArrayBlockingQueue是一个由数组结构组成的有界阻塞队列,此队列按照FIFO的原则对元素进行排序 。
默认情况下不保证线程公平的访问队列,所谓公平的访问队列是指阻塞的线程,可以按照阻塞的先后顺序访问队列,即先阻塞线程先访问队列。非公平性是对先等待的线程是非公平的,当队列可用时,阻塞的线程都可以争夺队列的资格,有可能先阻塞的队列最后才访问队列。为了保证公平性通常都会降低吞吐量。下面的代码可以创建一个公平的阻塞队列:
ArrayBlockingQueue fairQueue = new ArrayBlockingQueue(,true);
访问者的公平性是通过可重入锁实现的,构造函数如下:
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
ArrayBlockingQueue使用一个Object数组保存数据,一个int类型的count表示当前队列添加的元素个数,有界保证依靠的两个Condition对象,下面看一下put()方法,代码如下:
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
//判断队列是否已满
while (count == items.length)
//如果已经满了,等待
notFull.await();
//插入
insert(e);
} finally {
lock.unlock();
}
}
private void insert(E x) {
items[putIndex] = x;
putIndex = inc(putIndex);//加1
++count;
notEmpty.signal();
}
ArrayBlockingQueue在执行put操作时,首先获取锁,然后判断插入队列是否已满,如果队列已满则等待,否则顺利插入,并且执行一次notEmpty.signal()唤醒有可能队列为空的情况下执行take()操作在等待的线程 ,take()方法代码如下:
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
//如果队列为空,则等待元素入队
while (count == 0)
notEmpty.await();
return extract();
} finally {
lock.unlock();
}
}
private E extract() {
final Object[] items = this.items;
E x = this.<E>cast(items[takeIndex]);
items[takeIndex] = null;
takeIndex = inc(takeIndex);
--count;
notFull.signal();
return x;
}
take操作也是先判断队列是否为空,为空则等待,不为空则返回items[takeIndex] ,并且执行notFull.signal()唤醒可能在等待put操作的线程。
2.LinkedBlockingQueue
Java里的阻塞队列的更多相关文章
- Java中的阻塞队列
1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用 ...
- 聊聊并发(七)——Java中的阻塞队列
3. 阻塞队列的实现原理 聊聊并发(七)--Java中的阻塞队列 作者 方腾飞 发布于 2013年12月18日 | ArchSummit全球架构师峰会(北京站)2016年12月02-03日举办,了解更 ...
- Java中的阻塞队列-ArrayBlockingQueue(一)
最近在看一些java基础的东西,看到了队列这章,打算对复习的一些知识点做一个笔记,也算是对自己思路的一个整理,本章先聊聊java中的阻塞队列 参考文章: http://ifeve.com/java-b ...
- java 中的阻塞队列
1.什么是阻塞队列: 支持阻塞的插入方法,意思是当队列满时,队列会阻塞插入元素的线程,知道队列不满. 支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空. 插入和移除操作的4种处 ...
- java并发:阻塞队列
第一节 阻塞队列 1.1 初识阻塞队列 队列以一种先进先出的方式管理数据,阻塞队列(BlockingQueue)是一个支持两个附加操作的队列,这两个附加的操作是:在队列为空时,获取元素的线程会等待队列 ...
- Java中的阻塞队列(BlockingQueue)
1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...
- JUC之Java中的阻塞队列及其实现原理
在文章线程池实现原理 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍了线程池的组成部分,其中一个组成部分就是阻塞队列.那么JAVA中的阻塞队列如何实现的呢? 阻塞队列,关键字是阻塞 ...
- Java并发编程-阻塞队列(BlockingQueue)的实现原理
背景:总结JUC下面的阻塞队列的实现,很方便写生产者消费者模式. 常用操作方法 常用的实现类 ArrayBlockingQueue DelayQueue LinkedBlockingQueue Pri ...
- 多线程编程学习六(Java 中的阻塞队列).
介绍 阻塞队列(BlockingQueue)是指当队列满时,队列会阻塞插入元素的线程,直到队列不满:当队列空时,队列会阻塞获得元素的线程,直到队列变非空.阻塞队列就是生产者用来存放元素.消费者用来获取 ...
随机推荐
- Eclipse Memory Analyzer安装
转载:http://www.jianshu.com/p/3b3c3a914724 1.下载地址:Eclipse Memory Analyzer Open Source Project 2.点击进入 ...
- 手动脱Mole Box壳实战总结
作者:Fly2015 这个程序是吾爱破解脱壳练习第8期的加壳程序,该程序的壳是MoleBox V2.6.5壳,这些都是广告,能够直接无视了.前面的博客手动脱Mole Box V2.6.5壳实战中已经给 ...
- AutoCAD如何输入文字
1 运行文字命令(这里使用单行文字),然后鼠标点击文字的起始点,如图所示 2 鼠标分别向上和向右移动一定距离,表示文字的高度(文字的大小)和文字的旋转角度(一般向右,因为是水平文字) 3 最后 ...
- Python 可视化Twitter中指定话题中Tweet的词汇频率
CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-7-8 @author: guaguastd @name: pl ...
- vuex mapState使用
<template> <div> {{count}} <button @click="handleIncrease">+5</button ...
- VueJS自定义全局和局部指令
除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令. 使用directive自定义全局指令 下面我们注册一个全局指令 v-focus, 该指令的功能是在页面 ...
- deeplearning.net 0.1 document - Multilayer Perceptron
Multilayer Perceptron 以下我们使用Theano来介绍一下单隐藏层的多层感知机(MLP).MLP能够看成一个logistic回归分类器,它使用一个已经学习的非线性转换器处理输入.这 ...
- MVC项目总结
View命名 View下有多个模块的文件夹,我们根据微软的规定,每个模块下的首页都为Index.cshtml命名 获得当前页面的控制器名称 var currentControllerName = th ...
- Web大文件(夹)上传(断点续传)控件-Xproer.HttpUploader6
版权所有 2009-2017荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...
- Appium python unittest pageobject如何实现加载多个case
学习了Appium python项目施展的课程小伙伴都会有一个疑问,说现在所有的case都是通过一个suite进行一个方法一个方法进行添加的,但是在实际过程中我们不希望这样,我们做出来的功能是这样: ...