阻塞场景 
BlockingQueue阻塞队列,阻塞的情况主要有如下2种: 
1. 当队列满了,进行入队操作阻塞 
2. 当队列空了,进行出队操作阻塞 
阻塞队列主要用在生产者/消费者模式中,下图展示了一个线程生产,一个线程消费的场景:

BlockingQueue接口

操作 抛异常 特殊值 阻塞 超时
插入 add(o) offer(o) put(o) offer(o,timeout,unit)
删除 remove(o) poll() take() poll(timeout,unit)

1. 抛出异常:如果操作不能马上进行,则抛出异常。 
2. 特殊值:如果操作不能马上进行,将会返回一个特殊的值,一般是true/false。 
3. 阻塞:如果操作不能马上进行,操作会阻塞。 
4. 超时:如果操作不能马上进行,操作会阻塞指定时间,如果指定时间没执行,则返回一个特殊值,一般为true/false。 
不能向BlockingQueue中插入null.否则会报NullPointerException异常。 
BlockingQueue子类 
由以上的图片可以知道BlockingQueue具有如下的几个子类: 
1. ArrayBlockingQueue 
2. DelayQueue 
3. LinkedBlockingQueue 
4. PriorityBlockingQueue 
5. SynchronousQueue

ArrayBlockingQueue 
一个有边界的(容量是有限的)阻塞队列,它的内部实现是一个数组。必须在初始化的时候指定它的容量大小,容量大小一旦指定就不可改变。ArrayBlockingQueue是以先进先出的方式存储数据,最新插入的对象是尾部,最新移除的对象是头部。

public class ArrayBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
/** The queued items */
final Object[] items;
public ArrayBlockingQueue(int capacity)
public ArrayBlockingQueue(int capacity, boolean fair)
public ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c)
}

LinkedBlockingQueue 
队列大小的配置是可选的,如果我们初始时指定一个大小,它就是有边界的,如果不指定它就是无边界采用默认值Integer.MAX_VALUE的容量,它的内部是一个链表。

public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
public LinkedBlockingQueue();
public LinkedBlockingQueue(int capacity);
public LinkedBlockingQueue(Collection<? extends E> c);
}

PriorityBlockingQueue 
是一个没有边界的队列,它的排序规则和ProrityQueue一样,需要注意,PriorityBlockingQueue中允许插入null对象。 
所有插入PriorityBlockingQueue队列的对象必须实现Comparable接口,队列优先级的排序规则就是按照我们队这个接口的实现来定义的。 
另外PriorityBlockingQueue可以获得一个Iterator,但是这个迭代器并不保证按照优先级顺序进行迭代。

package org.github.lujiango;

import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.PriorityBlockingQueue; class PriorityElement implements Comparable<PriorityElement> {
private int priority; public PriorityElement(int priority) {
this.priority = priority;
} @Override
public int compareTo(PriorityElement o) { return priority >= o.priority ? 1 : -1;
} @Override
public String toString() {
return "PriorityElement[priority= " + priority + "]";
} } public class Test13 { public static void main(String[] args) throws InterruptedException {
PriorityBlockingQueue<PriorityElement> queue = new PriorityBlockingQueue<PriorityElement>();
for (int i = 0; i < 5; i++) {
Random rand = new Random();
PriorityElement ele = new PriorityElement(rand.nextInt(10));
queue.put(ele);
}
System.out.println("Iterator----------------");
Iterator<PriorityElement> it = queue.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("PriorityBlockingQueue.tak()-----------");
while (!queue.isEmpty()) {
System.out.println(queue.take());
}
}
}

SynchronousQueue 
内部仅仅容纳一个元素,当一个线程插入一个元素之后就被阻塞(放入元素的线程立刻被阻塞),除非这个元素被另一个线程消费。

package org.github.lujiango;

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit; class MyThread1 implements Runnable {
private SynchronousQueue<String> queue; public MyThread1(SynchronousQueue<String> queue) {
this.queue = queue;
} @Override
public void run() { try {
TimeUnit.SECONDS.sleep(3);
System.out.println("take a from queue...");
queue.take();
} catch (InterruptedException e) {
}
}
} public class Test14 { public static void main(String[] args) throws InterruptedException {
SynchronousQueue<String> queue = new SynchronousQueue<String>();
Thread t = new Thread(new MyThread1(queue));
t.start();
System.out.println("put a into queue...");
queue.put("a"); } }

DelayQueue 
DelayQueue阻塞的是其内部元素,DelayQueue中的元素必须实现Delayed接口。

public interface Delayed extends Comparable<Delayed> {

    /**
* Returns the remaining delay associated with this object, in the
* given time unit.
*
* @param unit the time unit
* @return the remaining delay; zero or negative values indicate
* that the delay has already elapsed
*/
long getDelay(TimeUnit unit);
}

getDelay()返回值就是队列元素被释放前的存活时间,如果返回<=0,就意味着该元素已经到期需要被释放,此时DelayedQueue会通过其take()方法释放此对象,如无可释放(超期元素)元素,则take方法会阻塞。

package org.github.lujiango;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit; class DelayedElement implements Delayed {
private long expired;
private long delay;
private String name; public DelayedElement(String name, long delay) {
this.name = name;
this.delay = delay;
this.expired = (delay + System.currentTimeMillis());
} @Override
public int compareTo(Delayed o) {
DelayedElement cache = (DelayedElement) o;
return cache.expired > expired ? 1 : -1;
} @Override
public long getDelay(TimeUnit unit) {
return (expired - System.currentTimeMillis());
} @Override
public String toString() {
return "DelayedElement[delay=" + delay + ",name=" + name + "]";
} } public class Test15 { public static void main(String[] args) throws InterruptedException {
DelayQueue<Delayed> queue = new DelayQueue<Delayed>();
DelayedElement ele = new DelayedElement("3s", 3000);
queue.put(ele);
System.out.println(queue.take());
} }

DelayQueue的应用场景很多,比如定时关闭连接,缓存对象,超时处理等各种场景。

多线程-BlockingQueue,Array[Linked]BlockingQueue,DelayQueue,PriorityBlockingQueue,SynchronousQueue的更多相关文章

  1. JUC 并发编程--09, 阻塞队列: DelayQueue, PriorityBlockingQueue ,SynchronousQueue, 定时任务线程池: ScheduledThreadPoolExecutor

    先看DelayQueue 这个是用优先级队列实现的无界限的延迟队列,直接上代码: /** * 这个是 {@link DelayQueue} 延时队列 的验证使用类 */ class MyDelayed ...

  2. JAVA多线程之间共享数据BlockingQueue介绍

    在JAVA的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利. ...

  3. Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

  4. 集合类源码(五)Collection之BlockingQueue(LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue)

    LinkedTransferQueue 功能 全名 public class LinkedTransferQueue<E> extends AbstractQueue<E> i ...

  5. 多线程编程-工具篇-BlockingQueue

    在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序 ...

  6. Java线程和多线程(十一)——BlockingQueue

    这次讨论的是Java的BlockingQueue,java.util.concurrent.BlockingQueue是一个Java的队列接口,支持一系列操作,比如,在获取和移除对象的时候如果队列为空 ...

  7. 多线程-生产者消费者(BlockingQueue实现)

    三.采用BlockingQueue实现 BlockingQueue也是java.util.concurrent下的主要用来控制线程同步的工具. BlockingQueue有四个具体的实现类,根据不同需 ...

  8. 【java多线程】队列系统之DelayQueue源码

    一.延迟队列 延迟队列,底层依赖了优先级队列PriorityBlockingQueue 二.延迟队列案例 (1)延迟队列的任务 public class DelayTask implements De ...

  9. Java多线程系列十——BlockingQueue

    参考资料:http://ifeve.com/java-synchronousqueue/http://www.cnblogs.com/jackyuj/archive/2010/11/24/188655 ...

随机推荐

  1. gdb signal 转

    信号是一种软中断,是一种处理异步事件的方法.一般来说,操作系统都支持许多信号.尤其是UNIX,比较重要应用程序一般都会处理信号.UNIX定义了许 多信号,比如SIGINT表示中断字符信号,也就是Ctr ...

  2. ECSHOP中transport.js和jquery冲突的解决方法

    jQuery 和global.js 冲突 百度和google多次,根据网上的大多数建议和自己测试,解决办法如下:删除global.js 或者global.js 文件的10-13行屏蔽//Object. ...

  3. Log4j 日志级别

    转自:http://michales003.iteye.com/blog/1160605 日志记录器(Logger)是日志处理的核心组件.log4j具有5种正常级别(Level).: 1.static ...

  4. 关于Java设计模式的一些概况

    设计模式(Design pattern)在软件行业一直都扮演着很重要的角色.最近感觉自己对设计模式的知识有些遗忘了,虽然以前也看了很多,但是坦白说,其实并没有怎么理解.基本还是为了应付面试.然后,在工 ...

  5. soap-学习

    1. SOAP 是一种简单的基于 XML 的协议,它使应用程序通过 HTTP 来交换信息. 简单的说:SOAP是用于访问网络服务的协议. 2. 什么是SOAP SOAP 指简易对象访问协议 SOAP ...

  6. 对Emlog 6.0 Beta的完整代码审计过程

    Emlog 6.0 beta版本,这可能是最后一篇关于PHP语言CMS的代码审计文章,此次将详细记录完整的审计过程. 文章基本上完整记录小东的对此CMS审计过程,或许显得繁琐,但代码审计的过程就是这样 ...

  7. nginx最大并发连接数的思考:worker_processes、worker_connections、worker_rlimit_nofile

    参考nginx官网:http://nginx.org/en/docs/ngx_core_module.html#worker_connections 从用户的角度,http 1.1协议下,由于浏览器默 ...

  8. C#++c1FlexGrid+帮助文档09

    摘自: http://3y.uu456.com/bp-e2746s16s2d380eb62946d27-1.html C#:c1FlexGrid帮助文档:Value-MappedLists(值映射列表 ...

  9. Json.net说法——(一)修饰标签,日期序列化

    摘自: http://www.cnblogs.com/jams742003/archive/2009/12/24/1631587.html 通过属性标签自定义JSON序列化 JsonObjectAtt ...

  10. Centos&RHEL 6安装图形化

    Linux是一个多任务的多用户的操作系统,而在安装linux的时候经常遇到的问题-没有图形化桌面.在上节中我们演示了RHEL7安装图形化的过程,下面我们演示Centos6的图形化安装. 一.Cento ...