【Java并发】【ArrayBlockingQueue】适合初学体质的ArrayBlockingQueue入门

👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD

🔥 2025本人正在沉淀中... 博客更新速度++

👍 欢迎点赞、收藏、关注,跟上我的更新节奏

📚欢迎订阅专栏,专栏名《在2B工作中寻求并发是否搞错了什么》

什么是ArrayBlockingQueue

ArrayBlockingQueue是 Java 并发编程中一个基于数组实现的有界阻塞队列,属于 java.util.concurrent 包,实现了 BlockingQueue 接口。

具有以下特性:

有界性

  • 队列容量在创建时固定,无法动态扩容(必须显式指定初始容量)。
  • 适合需要控制资源使用的场景,避免无限制增长导致内存溢出。

线程安全

  • 内部通过 ReentrantLock 保证并发操作的安全性。
  • 采用"单锁双条件"(一个锁管理入队和出队条件)实现同步。

阻塞操作

  • 队列满时:put(e) 方法会阻塞,直到有空间可用。
  • 队列空时:take() 方法会阻塞,直到有新元素加入。

FIFO 原则

  • 元素按先进先出顺序处理,保证公平性。

使用ArrayBlockingQueue

构造方法

java 复制代码
// 指定容量(必须)
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);

// 指定容量和公平性(true 表示公平锁)
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10, true);

// 指定容量、公平性,并初始化集合
List<Integer> list = Arrays.asList(1, 2, 3);
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10, true, list);

阻塞使用(put、take)

put(E e)方法: 阻塞当前线程生产(往队列中塞数据)

java 复制代码
// 生产者线程
new Thread(() -> {
    try {
        for (int i = 0; i < 5; i++) {
            queue.put(i); // 队列满时阻塞
            System.out.println("生产: " + i);
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}).start();

take()方法: 阻塞当前线程消费(往队列里面取数据)。

java 复制代码
// 消费者线程
new Thread(() -> {
    try {
        while (true) {
            Integer value = queue.take(); // 队列空时阻塞
            System.out.println("消费: " + value);
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}).start();

非阻塞方法使用(offer、poll)

offer(E e)方法:尝试插入,队列满时直接返回 false。

java 复制代码
boolean success = queue.offer(100);
System.out.println("插入是否成功: " + success); 

poll()方法:尝试取出,队列空时返回 null。

java 复制代码
Integer value = queue.poll();
System.out.println("取出值: " + value);

不建议使用的非阻塞方法(add、remove、element)

add和element这种方法,会直接抛出异常。

add(E e): 向阻塞队列放入元素,阻塞队列满的话,直接抛出IllegalStateException异常。

java 复制代码
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(1); // 容量为1

queue.add(10); // 成功插入
try {
    queue.add(20); // 队列已满,抛出 IllegalStateException
} catch (IllegalStateException e) {
    System.out.println("队列已满,add() 抛异常: " + e);
}

// AbstractQueue#add
// 抛出IllegalStateException异常
public boolean add(E e) {
    if (offer(e))
        return true;
    else
        throw new IllegalStateException("Queue full");	// 阻塞队满,抛出异常
}

elemet(): 向阻塞队列获取元素,阻塞队列为空的话,直接抛出NoSuchElementException异常。

java 复制代码
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(1); // 空队列

try {
    Integer head = queue.element(); // 队列为空,抛出 NoSuchElementException
} catch (NoSuchElementException e) {
    System.out.println("队列为空,element() 抛异常: " + e);
}

// AbstractQueue#element
public E element() {
    E x = peek();
    if (x != null)
        return x;
    else
        throw new NoSuchElementException(); // 阻塞队列为空,抛出异常
}

remove(): 删除阻塞队列的头元素,并返回这个头元素。如果阻塞队列为空,直接抛出NoSuchElementException异常。

java 复制代码
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(1); // 空队列
queue.remove();	// NoSuchElementException异常

public E remove() {
    E x = poll();
    if (x != null)
        return x;
    else
        throw new NoSuchElementException();	// 阻塞队列为空,抛出异常
}

超时阻塞使用(offer、poll)

也是offer方法,只是多传了时间相关的参数。

offer(e, time, unit): 等待time秒后,插入数据,返回执行结果。

java 复制代码
// 生产者等待2秒插入
boolean success = queue.offer(200, 2, TimeUnit.SECONDS);

poll(time, unit) :等待time秒后获取数据,队列为空的话,返回null。

java 复制代码
// 消费者等待3秒取出
Integer value = queue.poll(3, TimeUnit.SECONDS);

后话

主播这么快又结束了?没有的!宝子,还有呢!

关注点给主播点上,下一篇主播给大家表演看源码。

相关推荐
程序猿阿越4 分钟前
Kafka源码(七)事务消息
java·后端·源码阅读
m0_748248025 分钟前
C++20 协程:在 AI 推理引擎中的深度应用
java·c++·人工智能·c++20
笑我归无处5 分钟前
强引用、软引用、弱引用、虚引用详解
java·开发语言·jvm
02苏_5 分钟前
秋招Java面
java·开发语言
爱吃甜品的糯米团子26 分钟前
详解 JavaScript 内置对象与包装类型:方法、案例与实战
java·开发语言·javascript
ArabySide28 分钟前
【Spring Boot】REST与RESTful详解,基于Spring Boot的RESTful API实现
spring boot·后端·restful
程序定小飞1 小时前
基于springboot的学院班级回忆录的设计与实现
java·vue.js·spring boot·后端·spring
攀小黑1 小时前
基于若依-内容管理动态修改,通过路由字典配置动态管理
java·vue.js·spring boot·前端框架·ruoyi
青云交2 小时前
Java 大视界 -- 基于 Java 的大数据可视化在城市空气质量监测与污染溯源中的应用
java·spark·lstm·可视化·java 大数据·空气质量监测·污染溯源
森语林溪2 小时前
大数据环境搭建从零开始(十七):JDK 17 安装与配置完整指南
java·大数据·开发语言·centos·vmware·软件需求·虚拟机