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

简介: 什么是ArrayBlockingQueue ArrayBlockingQueue是 Java 并发编程中一个基于数组实现的有界阻塞队列,属于 java.util.concurrent 包,实现了 Bl...

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

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

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

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

什么是ArrayBlockingQueue

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

有界性

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

线程安全

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

阻塞操作

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

FIFO 原则

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

使用ArrayBlockingQueue

构造方法

image.png

// 指定容量(必须)
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)方法: 阻塞当前线程生产(往队列中塞数据)

// 生产者线程
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()方法: 阻塞当前线程消费(往队列里面取数据)。

// 消费者线程
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。

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

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

Integer value = queue.poll();
System.out.println("取出值: " + value);

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

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

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

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异常。

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异常。

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秒后,插入数据,返回执行结果。

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

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

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

后话

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

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

目录
相关文章
|
22天前
|
Java
java入门代码示例
本文介绍Java入门基础,包含Hello World、变量类型、条件判断、循环及方法定义等核心语法示例,帮助初学者快速掌握Java编程基本结构与逻辑。
230 0
|
1月前
|
Java API 数据库
2025 年最新 Java 实操学习路线,从入门到高级应用详细指南
2025年Java最新实操学习路线,涵盖从环境搭建到微服务、容器化部署的全流程实战内容,助你掌握Java 21核心特性、Spring Boot 3.2开发、云原生与微服务架构,提升企业级项目开发能力,适合从入门到高级应用的学习需求。
381 0
|
1月前
|
前端开发 Java 数据库连接
帮助新手快速上手的 JAVA 学习路线最详细版涵盖从入门到进阶的 JAVA 学习路线
本Java学习路线涵盖从基础语法、面向对象、异常处理到高级框架、微服务、JVM调优等内容,适合新手入门到进阶,助力掌握企业级开发技能,快速成为合格Java开发者。
335 3
|
1月前
|
监控 Java API
2025 年全新出炉的 Java 学习路线:从入门起步到实操精通的详细指南
2025年Java学习路线与实操指南,涵盖Java 21核心特性、虚拟线程、Spring Boot 3、微服务、Spring Security、容器化部署等前沿技术,助你从入门到企业级开发进阶。
314 0
|
2月前
|
NoSQL Java 关系型数据库
Java 从入门到进阶完整学习路线图规划与实战开发最佳实践指南
本文为Java开发者提供从入门到进阶的完整学习路线图,涵盖基础语法、面向对象、数据结构与算法、并发编程、JVM调优、主流框架(如Spring Boot)、数据库操作(MySQL、Redis)、微服务架构及云原生开发等内容,并结合实战案例与最佳实践,助力高效掌握Java核心技术。
249 1
|
2月前
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
2月前
|
Java 编译器 API
Java Lambda表达式与函数式编程入门
Lambda表达式是Java 8引入的重要特性,简化了函数式编程的实现方式。它通过简洁的语法替代传统的匿名内部类,使代码更清晰、易读。本文深入讲解Lambda表达式的基本语法、函数式接口、方法引用等核心概念,并结合集合操作、线程处理、事件回调等实战案例,帮助开发者掌握现代Java编程技巧。同时,还解析了面试中高频出现的相关问题,助你深入理解其原理与应用场景。
|
2月前
|
安全 Java 数据库连接
2025 年最新 Java 学习路线图含实操指南助你高效入门 Java 编程掌握核心技能
2025年最新Java学习路线图,涵盖基础环境搭建、核心特性(如密封类、虚拟线程)、模块化开发、响应式编程、主流框架(Spring Boot 3、Spring Security 6)、数据库操作(JPA + Hibernate 6)及微服务实战,助你掌握企业级开发技能。
344 3
|
2月前
|
算法 Java 测试技术
零基础学 Java: 从语法入门到企业级项目实战的详细学习路线解析
本文为零基础学习者提供完整的Java学习路线,涵盖语法基础、面向对象编程、数据结构与算法、多线程、JVM原理、Spring框架、Spring Boot及项目实战,助你从入门到进阶,系统掌握Java编程技能,提升实战开发能力。
155 0
|
2月前
|
前端开发 Java 数据库
Java 项目实战从入门到精通 :Java Web 在线商城项目开发指南
本文介绍了一个基于Java Web的在线商城项目,涵盖技术方案与应用实例。项目采用Spring、Spring MVC和MyBatis框架,结合MySQL数据库,实现商品展示、购物车、用户注册登录等核心功能。通过Spring Boot快速搭建项目结构,使用JPA进行数据持久化,并通过Thymeleaf模板展示页面。项目结构清晰,适合Java Web初学者学习与拓展。
205 1

热门文章

最新文章