阻塞队列介绍

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

阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列,下图展示了如何通过阻塞队列来合作:

线程1往阻塞队列中添加元素,而线程2从阻塞队列中移除元素

BlockingQueue接口方法

public interface BlockingQueue<E> extends Queue<E> {//将给定元素设置到队列中,如果设置成功返回true, 否则返回false。如果是往限定了长度的队列中设置值,推荐使用offer()方法。 如果队列已满,则抛出一个IIIegaISlabEepeplian异常,不可add nullboolean add(E e);//将给定的元素设置到队列中,如果设置成功返回true, 否则返回false. e的值不能为空,否则抛出空指针异常。boolean offer(E e);//将元素设置到队列中,如果队列中没有多余的空间,该方法会一直阻塞,直到队列中有多余的空间。void put(E e) throws InterruptedException;//将给定元素在给定的时间内设置到队列中,如果设置成功返回true, 否则返回false.boolean offer(E e, long timeout, TimeUnit unit)throws InterruptedException;//从队列中获取值,如果队列中没有值,线程会一直阻塞,直到队列中有值,并且该方法取得了该值。E take() throws InterruptedException;//在给定的时间里,从队列中获取值,时间到了直接调用普通的poll方法,为null则直接返回null。E poll(long timeout, TimeUnit unit)throws InterruptedException;//获取队列中剩余的空间。int remainingCapacity();//从队列中移除指定的值。boolean remove(Object o);//判断队列中是否拥有该值。public boolean contains(Object o);//将队列中值,全部移除,并发设置到给定的集合中。int drainTo(Collection<? super E> c);//指定最多数量限制将队列中值,全部移除,并发设置到给定的集合中。int drainTo(Collection<? super E> c, int maxElements);
}

阻塞队列实现

队列 有界性 数据结构
ArrayBlockingQueue bounded(有界) 加锁 arrayList
LinkedBlockingQueue optionally-bounded 加锁 linkedList
PriorityBlockingQueue unbounded 加锁 heap
DelayQueue unbounded 加锁 heap
SynchronousQueue bounded 加锁
LinkedTransferQueue unbounded 加锁 heap
LinkedBlockingDeque unbounded 无锁 heap

下面分别简单介绍一下:

  • ArrayBlockingQueue:是一个用数组实现的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序。支持公平锁和非公平锁。【注:每一个线程在获取锁的时候可能都会排队等待,如果在等待时间上,先获取锁的线程的请求一定先被满足,那么这个锁就是公平的。反之,这个锁就是不公平的。公平的获取锁,也就是当前等待时间最长的线程先获取锁】。参考:ArrayBlockingQueue源码

  • LinkedBlockingQueue:一个由链表结构组成的有界队列,此队列的长度为Integer.MAX_VALUE。此队列按照先进先出的顺序进行排序。参考:LinkedBlockingQueue源码
  • PriorityBlockingQueue: 一个支持线程优先级排序的无界队列,默认自然序进行排序,也可以自定义实现compareTo()方法来指定元素排序规则,不能保证同优先级元素的顺序。参考:PriorityBlockingQueue源码
  • DelayQueue: 一个实现PriorityBlockingQueue实现延迟获取的无界队列,在创建元素时,可以指定多久才能从队列中获取当前元素。只有延时期满后才能从队列中获取元素。(DelayQueue可以运用在以下应用场景:1.缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取元素时,表示缓存有效期到了。2.定时任务调度。使用DelayQueue保存当天将会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,从比如TimerQueue就是使用DelayQueue实现的。)。参考:DelayQueue源码
  • SynchronousQueue: 一个不存储元素的阻塞队列,每一个put操作必须等待take操作,否则不能添加元素。支持公平锁和非公平锁。SynchronousQueue的一个使用场景是在线程池里。Executors.newCachedThreadPool()就使用了SynchronousQueue,这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。参考:SynchronousQueue解析
  • LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列,相当于其它队列,LinkedTransferQueue队列多了transfer和tryTransfer方法。
  • LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。队列头部和尾部都可以添加和移除元素,多线程并发时,可以将锁的竞争最多降到一半。参考:LinkedBlockingDeque源码

方法实现

继承自AbstractQueue的方法

    public boolean add(E e) {if (offer(e))return true;elsethrow new IllegalStateException("Queue full");}public E remove() {E x = poll();if (x != null)return x;elsethrow new NoSuchElementException();}public E element() {E x = peek();if (x != null)return x;elsethrow new NoSuchElementException();}public void clear() {while (poll() != null);}public boolean addAll(Collection<? extends E> c) {if (c == null)throw new NullPointerException();if (c == this)throw new IllegalArgumentException();boolean modified = false;for (E e : c)if (add(e))modified = true;return modified;}

示例

DelayQueue

java中DelayQueue的一个使用陷阱分析

Java并发包--阻塞队列(BlockingQueue)相关推荐

  1. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

  2. java阻塞队列作用_简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用...

    简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用 Condition:可以理解成一把锁的一个钥匙,它既可以解锁(通知放行),又可以加锁(阻塞) n ...

  3. java 阻塞队列 BQ_阻塞队列 BlockingQueue的使用(二)

    原 阻塞队列 BlockingQueue的使用(二) BlockingQueue 的核心方法:方法类型抛出异常特殊值阻塞超时 插入add(e)offer(e)put(e)offer(e,time,un ...

  4. java concurrenthashmap与阻塞队列

    https://blog.csdn.net/wozniakzhang/article/details/108106205 Java~并发容器ConcurrentHashMap.ConcurrentLi ...

  5. 聊聊并发(七)——Java中的阻塞队列

    1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用 ...

  6. 转:Java 7 种阻塞队列详解

    转自: Java 7 种阻塞队列详解 - 云+社区 - 腾讯云队列(Queue)是一种经常使用的集合.Queue 实际上是实现了一个先进先出(FIFO:First In First Out)的有序表. ...

  7. 并发编程-concurrent指南-阻塞队列BlockingQueue

    阻塞队列BlockingQueue,java.util.concurrent下的BlockingQueue接口表示一个线程放入和提取实例的队列. 适用场景: BlockingQueue通常用于一个线程 ...

  8. Java面试之阻塞队列

    阻塞队列 概念 队列 队列就可以想成是一个数组,从一头进入,一头出去,排队买饭(FIFO),和栈是一样的FIFO 阻塞队列 BlockingQueue 阻塞队列,排队拥堵,首先它是一个队列,而一个阻塞 ...

  9. 阻塞队列BlockingQueue源码

    JAVA阻塞队列 在学习线程池框架ThreadPoolExecutor时发现线程池的实现依赖到了阻塞队列BlockingQueue,在队列为空时take方法会阻塞当前线程,因此这里以ThreadPoo ...

最新文章

  1. linux中文麻酱字_【树】Linux笔记 1
  2. 汇编试验十五:安装新的int 9中断例程
  3. android timer弹出窗口,android – 如何在服务类中的Timer内显示AlertDialog?
  4. 年终凡尔赛,都是别人家的公司...
  5. 【深度学习的数学】卷积神经网络的搭建
  6. Applese 的大奖
  7. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现
  8. 工作121:[““]进行变量赋值
  9. Linux虚拟化KVM-Qemu分析(五)之内存虚拟化
  10. 在PostgreSQL中解码Django会话
  11. php汽车找车位,自动找车位+停车?这样的车5个月后就要交付给用户了!
  12. php curl 伪造IP来源的代码分享
  13. android封装全局调用的toast_自定义Toast,解决系统Toast存在的问题
  14. vue页面引用百度地图怎么让百度logo不显示
  15. 如何分享带淘宝客的链接到新浪微博
  16. ARCGIS近邻分析应用详解
  17. 打造私人搜书系统之系统设计
  18. Android无线蓝牙开发总结
  19. Hadoop大数据基础知识点总结--持续更新
  20. 企业测试环境部署(一)

热门文章

  1. usb4-配置usb触摸屏
  2. 【Spring学习】spring动态配置多数据源
  3. 并发编程之Synchronized
  4. XManager 远程连接Netbackup图形用户界面
  5. 潮美之夜见证“夜拍王”诞生,荣耀10 GT照亮三里屯
  6. 如何修改Fiori Launchpad里Tile计数调用的时间间隔
  7. Windows Hyper-V远程信息泄露漏洞CVE-2017-8712 影响Win2016和win10
  8. 词法、语法与语义相关知识
  9. MYSQL 更改数据库data存储目录 创建用户 创建权限 设置远程访问的权限.
  10. VMware vSAN紧盯虚拟化应用