轩辕李的博客 轩辕李的博客
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • HTML&CSS
  • JavaScript
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

轩辕李

勇猛精进,星辰大海
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • HTML&CSS
  • JavaScript
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Java

    • 核心

    • 并发

      • Java并发-线程基础与synchronized关键字
      • Java并发-重入锁ReetrantLock的使用
      • Java并发-信号量Semaphore
      • Java并发-读写锁ReadWriteLock
      • Java并发-倒计时器CountDownLatch
      • Java并发-栅栏CyclicBarrier
      • Java并发-LockSupport线程阻塞工具类
      • Java并发-线程池ThreadPoolExecutor
      • Java并发-阻塞队列BlockingQueue
        • 高性能队列
      • Java并发-以空间换时间之ThreadLocal
      • Java并发-无锁策略CAS与atomic包
      • Java并发-JDK并发容器
      • Java并发-异步调用结果之Future和CompletableFuture
      • Java并发-Fork Join框架
      • Java并发-调试与诊断
    • 经验

    • JVM

    • 企业应用

  • Spring

  • 其他语言

  • 工具

  • 后端
  • Java
  • 并发
轩辕李
2018-07-01
目录

Java并发-阻塞队列BlockingQueue

今天要讲的BlockingQueue可谓是大名鼎鼎,在并发编程中比较常见的一个类。
BlockingQueue顾名思义是表示一个阻塞队列,注意这两个词:阻塞和队列。可以拿我们熟悉的生产者-消费者队列来举例,一条流水线上,A生产零件,B组装零件,A就是生产者,B是消费者。如果A生成的太快,则零件堆积,A需要休息一会儿等待B把零件消费完;如果A生产的太慢,则B变得无活可干,被迫休息。
在BlockingQueue中offer()和put()就是把零件放到队列中,poll()和take()就是从队列中取出零件进行消费。需要注意的是put()和take()是阻塞方法,而offer()和poll()是非阻塞方法,也就是put()的时候队列满了,则阻塞;而offer()的时候队列满了,则返回false,不阻塞。take()和poll()方法同理。

BlockingQueue是一个接口,使用起来比较简单。他的实现类如下:
image
比较常用的是ArrayBlockingQueue和LinkedBlockingQueue,从名字也可以看出来,ArrayBlockingQueue适合做有界队列,LinkedBlockingQueue适合做无界队列。
这里只看一下简单使用:

ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
queue.put("abc");
queue.take();

一般来说put()和take()方法会分散在两个或多个线程中。


如果你的好奇心比较重,想研究一下BlockingQueue的实现原理,那么当你看一下ArrayBlockingQueue的源码,就会发现一些有趣的东西:

/** Main lock guarding all access */
final ReentrantLock lock;

/** Condition for waiting takes */
private final Condition notEmpty;

/** Condition for waiting puts */
private final Condition notFull;

这就涉及到我们前面文章讲过的ReentrantLock和Condition了。

# 高性能队列

强中自有强中手,对于要求高性能的系统来说,BlockingQueue还是会有一些局限。
以我们常用的ArrayBlockingQueue来说,他因为需要加锁,在某些场景下,可能会存在性能瓶颈。此时可以考虑业界著名的高性能队列:Disruptor。关于他的介绍,参见高性能队列——Disruptor (opens new window)

编辑 (opens new window)
#BlockingQueue
上次更新: 2024/10/25
Java并发-线程池ThreadPoolExecutor
Java并发-以空间换时间之ThreadLocal

← Java并发-线程池ThreadPoolExecutor Java并发-以空间换时间之ThreadLocal→

最近更新
01
Spring Boot版本新特性
09-15
02
Spring框架版本新特性
09-01
03
Spring Boot开发初体验
08-15
更多文章>
Theme by Vdoing | Copyright © 2018-2025 京ICP备2021021832号-2 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式