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)是指当队列满时,队列会阻塞插入元素的线程,直到队列不满:当队列空时,队列会阻塞获得元素的线程,直到队列变非空.阻塞队列就是生产者用来存放元素.消费者用来获取 ...
随机推荐
- perl的几个小tips
1.字符串比较 if($str eq "hello"){ ... } 字符串比较必须用eq,用==只适合标量 2.字符串连接 $str3=$str1."-".$ ...
- rsync一些常用的命令
渗透测试的时候会遇到RSYNC 匿名访问 在对一些大型互联网进行测试的时候经常会遇到rsync. 什么是Rsync Rsync(remote synchronize)是一个远程数据同步工具,可通过LA ...
- HDU 5301(Buildings-贪心构造)
Buildings Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Tota ...
- java监控工具jstatd-windows
Monitors Java Virtual Machines (JVMs) and enables remote monitoring tools to attach to JVMs. This co ...
- Java reference的种类及使用场景
Java 中一共有 4 种类型的引用 : StrongReference. SoftReference. WeakReference 以及 PhantomReference (传说中的幽灵引用).这 ...
- Java Swing界面编程(25)---事件处理:鼠标事件及监听处理
假设想对一个鼠标的操作进行监听,假设鼠标按下.松开等.则能够使用MouseListener接口. package com.beyole.util; import java.awt.event.Mous ...
- IE67实现inline-block布局
inline-block可以定义元素为行内块级元素,即既具有行内元素同占一行的特点,又具有块级元素的box模型.但是IE67和其他浏览器的支持差别比较大: 1.行内元素使用inline-block变成 ...
- [转]如何用C++实现一个LRU Cache
[转自http://hawstein.com/posts/lru-cache-impl.html] LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法 ...
- Android 中保存全局变量
作者:silence鼬.2015年6月28日 在学习Android的时候一直未context的问题认为头疼,由于想做一些工具类,可是又不是四大组件.总要来回传递context.认为非常麻烦,就想全局获 ...
- Laravel 5.4的本地化
简介 Laravel 的本地化功能提供方便的方法来获取多语言的字符串,让你的网站可以简单的支持多语言. 语言包存放在 resources/lang 目录下的文件里.在此目录中应该有应用对应支持的语言并 ...