java中的阻塞队列

前言

java中常用的数据结构就是集合和队列,我们之前的文章,对java中常用的一些集合都做了详细的介绍,那么今天我们就来看下另一个常用的数据结构,阻塞队列。

阻塞队列简介

阻塞队列就是支持两个附加操作的队列。两个附加的操作就是阻塞的插入和移除方法。
1.支持阻塞插入的方法就是:当队列满的时候,队列会阻塞插入元素的线程,直到队列不满。
2.支持阻塞移除的方法:就是在队列为空时,获取元素的线程会等待队列变为非空。

在阻塞队列不可用的时候,这两个附加操作提供了四种处理方式:
1.抛出异常:当队列满的时候,如果再往里插入元素,会抛出illegalstateexceptuon异常,当队列为空时获取元素,抛出nosuchelementexception异常。
2.返回特殊值:往队列里插入元素,插入成功返回true,否则返回false。如果是移除方法,则是从队列里取出一个元素,没有则返回null。
3.一直阻塞:当队列满的时候,如果生产者线程往队列里插入元素,队列会一直阻塞生产者线程,队列为空时,也是一样的道理。
4.超时退出:相当于给一直阻塞加了个时间,到这个时间如果还没操作成功,就直接退出。

Java里的阻塞队列

从下面这个图大家可以看出,所有的队列基本都实现了Queue接口,然后所有的双向对列,基本都实现了deque接口,而所有的阻塞队列,基本都实现了blockingQueue接口。那么我们今天就挑比较重要的七个阻塞队列介绍。
在这里插入图片描述

1.ArrayBlockingQuene:由一个数组实现的有界阻塞队列,按照先进先出原则,对元素进行排序,默认不保证线程公平访问队列(这个公平概念和公平锁的公平概念类似)。

2.LinkedBlockingQueue:一个链表实现的有界阻塞队列,也是先进先出原则对元素进行排序。

3.PriorityBlockingQueue:一个支持优先级的无界阻塞队列,通过compareto方法或者构造参数comparator来对元素进行排序。但是不能保证同优先级元素的顺序。

4.DelayQueue:支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列的元素必须实现Delayed接口。(这个队列使用场景很广泛如缓存系统设计,定时调度任务等等,这里不进行展开详细介绍,后续遇到,再进行详细介绍)

5.SynchronousQueue:是一个不存储元素的阻塞队列,每一个put操作,必须等待一个take操作,否则不能继续添加元素。支持公平访问队列,默认采用非公平策略。(这个后续介绍线程池的时候,大家还会再看到它)

6.LinkedTransferQueue:一个由链表组成的无界阻塞队列TransferQueue队列
这个队列有两个特色的方法
(1)transfer方法:如果当前有消费者在等待消费元素,transfer方法可以吧生产者传入的元素立即传输给消费者。
(2)tryTransfer方法:用来试探生产者传入的元素是否能直接传给消费者。如果没有消费者返回false。

7.LinkedBlockingDeque:由链表组成的双向阻塞队列,会被运用在工作窃取模式中(后续我们讲解Fork/Join框架的时候,大家就可以看到了)。

阻塞队列的实现原理

使用通知模式实现。所谓通知模式,就是当生产者往满的队列添加元素的时会阻塞住生产者,当消费者消费了一个队列之中的元素后,会通知生产者当前对列可用。这里我们就不展开详细介绍了,有兴趣的可以去阅读jdk源码,看下ArrayBlockingQueue的实现,它就是采用的这种模式,通过一个Contion属性实现的(和之前我们文章讲的线程之间的通信方式很像)。

总结

阻塞队列在单线程的场景下并不多见,它多被中在多线程的场景中。所以,学习好阻塞队列,对大家日后的解决多线程和高并发场景中的一些问题,会有很大的帮助。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mark---小鑫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值