阻塞场景 
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是以先进先出的方式存储数据,最新插入的对象是尾部,最新移除的对象是头部。

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

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

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

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

  1. package org.github.lujiango;
  2.  
  3. import java.util.Iterator;
  4. import java.util.Random;
  5. import java.util.concurrent.PriorityBlockingQueue;
  6.  
  7. class PriorityElement implements Comparable<PriorityElement> {
  8. private int priority;
  9.  
  10. public PriorityElement(int priority) {
  11. this.priority = priority;
  12. }
  13.  
  14. @Override
  15. public int compareTo(PriorityElement o) {
  16.  
  17. return priority >= o.priority ? 1 : -1;
  18. }
  19.  
  20. @Override
  21. public String toString() {
  22. return "PriorityElement[priority= " + priority + "]";
  23. }
  24.  
  25. }
  26.  
  27. public class Test13 {
  28.  
  29. public static void main(String[] args) throws InterruptedException {
  30. PriorityBlockingQueue<PriorityElement> queue = new PriorityBlockingQueue<PriorityElement>();
  31. for (int i = 0; i < 5; i++) {
  32. Random rand = new Random();
  33. PriorityElement ele = new PriorityElement(rand.nextInt(10));
  34. queue.put(ele);
  35. }
  36. System.out.println("Iterator----------------");
  37. Iterator<PriorityElement> it = queue.iterator();
  38. while (it.hasNext()) {
  39. System.out.println(it.next());
  40. }
  41. System.out.println("PriorityBlockingQueue.tak()-----------");
  42. while (!queue.isEmpty()) {
  43. System.out.println(queue.take());
  44. }
  45. }
  46. }

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

  1. package org.github.lujiango;
  2.  
  3. import java.util.concurrent.SynchronousQueue;
  4. import java.util.concurrent.TimeUnit;
  5.  
  6. class MyThread1 implements Runnable {
  7. private SynchronousQueue<String> queue;
  8.  
  9. public MyThread1(SynchronousQueue<String> queue) {
  10. this.queue = queue;
  11. }
  12.  
  13. @Override
  14. public void run() {
  15.  
  16. try {
  17. TimeUnit.SECONDS.sleep(3);
  18. System.out.println("take a from queue...");
  19. queue.take();
  20. } catch (InterruptedException e) {
  21. }
  22. }
  23. }
  24.  
  25. public class Test14 {
  26.  
  27. public static void main(String[] args) throws InterruptedException {
  28. SynchronousQueue<String> queue = new SynchronousQueue<String>();
  29. Thread t = new Thread(new MyThread1(queue));
  30. t.start();
  31. System.out.println("put a into queue...");
  32. queue.put("a");
  33.  
  34. }
  35.  
  36. }

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

  1. public interface Delayed extends Comparable<Delayed> {
  2.  
  3. /**
  4. * Returns the remaining delay associated with this object, in the
  5. * given time unit.
  6. *
  7. * @param unit the time unit
  8. * @return the remaining delay; zero or negative values indicate
  9. * that the delay has already elapsed
  10. */
  11. long getDelay(TimeUnit unit);
  12. }

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

  1. package org.github.lujiango;
  2.  
  3. import java.util.concurrent.DelayQueue;
  4. import java.util.concurrent.Delayed;
  5. import java.util.concurrent.TimeUnit;
  6.  
  7. class DelayedElement implements Delayed {
  8. private long expired;
  9. private long delay;
  10. private String name;
  11.  
  12. public DelayedElement(String name, long delay) {
  13. this.name = name;
  14. this.delay = delay;
  15. this.expired = (delay + System.currentTimeMillis());
  16. }
  17.  
  18. @Override
  19. public int compareTo(Delayed o) {
  20. DelayedElement cache = (DelayedElement) o;
  21. return cache.expired > expired ? 1 : -1;
  22. }
  23.  
  24. @Override
  25. public long getDelay(TimeUnit unit) {
  26. return (expired - System.currentTimeMillis());
  27. }
  28.  
  29. @Override
  30. public String toString() {
  31. return "DelayedElement[delay=" + delay + ",name=" + name + "]";
  32. }
  33.  
  34. }
  35.  
  36. public class Test15 {
  37.  
  38. public static void main(String[] args) throws InterruptedException {
  39. DelayQueue<Delayed> queue = new DelayQueue<Delayed>();
  40. DelayedElement ele = new DelayedElement("3s", 3000);
  41. queue.put(ele);
  42. System.out.println(queue.take());
  43. }
  44.  
  45. }

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. NodeJS搭建HTTP服务器

    NodeJS本来的用途是编写高性能Web服务器.我们首先在这里重复一下官方文档里的例子,使用NodeJS内置的http模块简单实现一个HTTP服务器. 新建server.js var http = r ...

  2. C语言基本数据类型简介

    1.概述 C 语言包含的数据类型如下图所示: 2.各种数据类型介绍 2.1整型 整形包括短整型.整形和长整形. 2.1.1短整形 short a=1; 2.1.2整形 一般占4个字节(32位),最高位 ...

  3. Android内存优化1 了解java内存分配 1

    开篇废话 今天我们一起来学习JVM的内存分配,主要目的是为我们Android内存优化打下基础. 一直在想以什么样的方式来呈现这个知识点才能让我们易于理解,最终决定使用方法为:图解+源代码分析. 欢迎访 ...

  4. NPD南京炮苑电子技术研究所----NPD治疗仪

    NPD南京炮苑电子技术研究所有限公司:    http://www.npd365.com/ 研发药物离子导入和中医定向透药技术.   南京炮苑玉古康2号NPD系列专用中医定向透药治疗仪腰颈椎疼痛贴 N ...

  5. HTML5中表单验证的8种方法

    HTML5中表单验证的8种方法 2012-4-21 11:00| 发布者: benben| 查看: 2765| 评论: 0 摘要: 前一篇,我们介绍了HTML5中新的表单特性和函数, 今天就继续来谈谈 ...

  6. javascript不依赖JS加载顺序事件对象实现

    背景: 在现在WEB开发中,稍复杂一点的页面,都会涉及到多个模块,尤其是类似seajs.LABjs.requireJS等模块工具出来后,前端开发者分模块开发已经慢慢变成一种习惯了,但是多个模块间的常常 ...

  7. [转]使用VS2010的Database 项目模板统一管理数据库对象

    本文转自:http://www.cnblogs.com/shanyou/archive/2010/05/08/1730810.html Visual Studio 2010 有一个数据库项目模板:Vi ...

  8. unity 实时间接光照 解决方案

    https://www.youtube.com/watch?v=D7LjsabD4V4 这个很强 他runtime bake lightprobe 之后走assetbundle加载 Place Pro ...

  9. maven工程小红叉处理方法

    搞了个Maven工程在Eclipse上,刚开始说JDK版本不对,编译的时候老报错误,很容易搞明白, 本地JDK版本为1.7.0_79: diamond operator is not supporte ...

  10. Java开发岗位面试题归类---怎么好好的准备面试,也算是发展学习方向

    转载:http://blog.csdn.net/qq_27093465/article/details/52181860 一.Java基础 1. String类为什么是final的. 自己找的参考答案 ...