阻塞队列简介及常见场景

本文介绍了Java中的阻塞队列BlockingQueue,它是一种线程安全的队列,提供了阻塞的插入和移除方法。 BlockingQueue在生产者/消费者模式中有广泛应用,常见的阻塞队列实现包括ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、DelayQueue和SynchronousQueue。ArrayBlockingQueue基于数组,适合生产者和消费者速度匹配的场景;LinkedBlockingQueue默认无界,适合动态增长的需求;PriorityBlockingQueue支持优先级排序;DelayQueue支持延迟获取元素;SynchronousQueue则是一个不存储元素的阻塞队列,适合传递性场景。
摘要由CSDN通过智能技术生成

BlockingQueue简介

BlockingQueue 继承了 Queue 接口,是队列的一种。Queue 和 BlockingQueue 都是在 Java 5
中加入的。阻塞队列(BlockingQueue)是一个在队列基础上又支持了两个附加操作的队列,两个附加操作(实现阻塞功能):
        支持阻塞的插入方法put: 队列满时,队列会阻塞插入元素的线程,直到队列不满。
        支持阻塞的移除方法take: 队列空时,获取元素的线程会等待队列变为非空

BlockingQueue常用方法示例


当队列满了无法添加元素,或者是队列空了无法移除元素时:
1. 抛出异常:add、remove、element
2. 返回结果但不抛出异常:offer、poll、peek
3. 阻塞:put、take

BlockingQueue应用场景


BlockingQueue 是线程安全的,我们在很多场景下都可以利用线程安全的队列来优雅地解决
我们业务自身的线程安全问题。

比如说,使用生产者/消费者模式的时候,我们生产者只需要往队列里添加元素,而消费者只需要从队列里取出它们就可以了。常见于类似于MQ之类的消息组件中

因为阻塞队列是线程安全的,所以生产者和消费者都可以是多线程的,不会发生线程安全问
题。生产者/消费者直接使用线程安全的队列就可以,而不需要自己去考虑更多的线程安全问题。
这也就意味着,考虑锁等线程安全问题的重任从“你”转移到了“队列”上,降低了我们开发的
难度和工作量

常见阻塞队列


BlockingQueue 接口的实现类都被放在了 juc 包中,它们的区别主要体现在存储结构上或对元素
操作上的不同,但是对于take与put操作的原理,却是类似的。

  • ArrayBlockingQueue                基于数组结构实现的一个有界阻塞队列
  • LinkedBlockingQueue              基于链表结构实现的一个无界阻塞队列,也可指定容量
  • PriorityBlockingQueue             支持按优先级排序的无界阻塞队列(初始有界,可不断扩容)
  • DelayQueue                             基于PriorityBlockingQueue实现的无界阻塞队列
  • SynchronousQueue                 不存储元素的阻塞队列
  • LinkedTransferQueue               基于链表结构实现的一个无界阻塞队列
  • LinkedBlockingDeque               基于链表结构实现的一个双端阻塞队列

ArrayBlockingQueue


ArrayBlockingQueue是最典型的有界阻塞队列,其内部是用数组存储元素的,初始化时需要
指定容量大小,利用 ReentrantLock 实现线程安全。
在生产者-消费者模型中使用时,如果生产速度和消费速度基本匹配的情况下,使用
ArrayBlockingQueue是个不错选择;当如果生产速度远远大于消费速度,则会导致队列填满,大
量生产线程被阻塞。
使用独占锁ReentrantLock实现线程安全,入队和出队操作使用同一个锁对象,也就是只能有
一个线程可以进行入队或者出队操作;这也就意味着生产者和消费者无法并行操作,在高并发场
景下会成为性能瓶颈。

LinkedBlockingQueue

LinkedBlockingQueue是一个基于链表实现的阻塞队列,默认情况下,该阻塞队列的大小为
Integer.MAX_VALUE,由于这个数值特别大,所以 LinkedBlockingQueue 也被称作无界队列
代表它几乎没有界限,队列可以随着元素的添加而动态增长,但是如果没有剩余内存,则队列
将抛出OOM错误。所以为了避免队列过大造成机器负载或者内存爆满的情况出现,我们在使用的
时候建议手动传一个队列的大小。
LinkedBlockingQueue内部由单链表实现,只能从head取元素,从tail添加元素。
LinkedBlockingQueue采用两把锁的锁分离技术实现入队出队互不阻塞,添加元素和获取元素都
有独立的锁,也就是说LinkedBl

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值