Java中的阻塞队列BlockingQueue

阻塞队列简介

阻塞队列是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移出方法。

  1. 支持阻塞的插入方法:意思是当队列满时,队列会阻塞插入元素的线程,直到队列不满
  2. 支持阻塞的移出方法:意思是当队列为空时,获取元素的线程会等待队列变成非空

在阻塞队列不可用时,这两个附加操作提供了4种处理方式:

  • 抛出异常:当队列满时,如果再往队列里擦汗如元素,会抛出IllegalStateException(“Queue Fulll”)异常。当队列空时,从队列里获取元素会抛出NoSuchElementException异常
  • 返回特殊值:当往队列插入元素时,会返回元素是否插入成功,成功返回true。如果是移除方法,则是从队列里取出一个元素,如果没有则返回null
  • 一直阻塞:当阻塞队列满时,如果生产者线程往队列里put元素,队列会一直阻塞生产者线程,直到队列可用或者响应中断推出。当队列空时,如果消费者线程从队列里take元素,队列会阻塞住消费者线程,直到队列不为空
  • 超时推出:当阻塞队列满时,如果生产者线程往队列里插入元素,队列会阻塞生产者线程一段时间,如果超过了指定时间,生产者线程就会退出

Java里的阻塞队列

JDK7提供了7个阻塞队列

  • ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列
  • LinkedBlockingQueue:一个由链表组成的有界阻塞队列。此队列的默认和最大长度为Interger.MAX_VALUE
  • PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。默认情况管辖元素采取自然顺序,升序排列。也可以自定义类实现compareTo()方法来指定元素排序规则
  • DelayQueue:一个使用优先级队列实现的无阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延迟期满时才能从队列中提取元素(常用于缓存有效期,定时任务调度等场景)
  • SynchronousQueue:一个不存储元素的阻塞队列。每一个put操作必须等待一个take操作,否则不能继续添加元素。队列本身不存储任何元素,非常适合传递性场景
  • LinkedTransferQueue:一个由链表结构组成的单向无界阻塞队列。它设计了一种直接在生产者和消费者之间传输元素的机制,成为“transfer”。当生产者调用transfer(e)方法时,它会阻塞直到有一个消费者接收该元素。适用于徐娅高效地在生产者和消费者之间直接传输数据的场景,尤其是当生产者和消费者之间的速度大致匹配时
  • LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。所谓双向队列指的是可以从队列的两端插入和移出元素。相比其他的阻塞队列,LinkedBlockingDeque多了addFirst、addLast、offer-First、offerLast、peekFirst和peekLast等方法。双向阻塞队列可以运用在“工作窃取”模式中。

阻塞队列的实现原理

如果队列是空的,消费者会一直等待,当生产者添加元素时,消费者是如何知道当前队列有元素的呢?

使用通知模式实现。所谓通知模式,当消费者从空的队列获取元素时,会阻塞住消费者,此时如果生产者放了一个元素进入队列,则需要通知阻塞住消费者当前有元素可取。同理当生产者往满的队列里添加元素时会阻塞住生产者,当消费者消费了一个队列中的元素后,会通知生产者当前队列可用

通过查看源码可知ArrayBlockingQueue使用了Condition来实现上述效果

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇