了解阻塞队列BlockingQueue和简单的API

简介: 了解阻塞队列BlockingQueue和简单的API

了解阻塞队列BlockingQueue


队列的特性:FIFO(先进先出)

其实就是写入和读取两个操作  写入和读取会有以下情况(不得不阻塞)

写入:如果队列满了,就必须阻塞等待(如果队列满了,就要阻塞等待,等其他队列出来了再进行写入操作)

读取:如果队列是空的,必须阻塞等待生产(读不到数据,需要先写入在进行读取)

阻塞队列:BlockingQueue 它其实是一个JUC下的接口并且和list,set同级,父类collection,实现类ArrayBlockingQueue(以数组实现的阻塞队列),LinkedBlockingQueue(以链表实现的阻塞队列),SynchronousQueue(同步队列)

它不是一个新的东西,和set,list同一级,都是collction下的接口,是一种更厉害的数据结构,它和Queue(队列,)是平级的,并且继承了Queue(队列,实现类有一个Deque(双端队列,也就是可以从左到右,从右到左执行,更加灵活多变),还有一个AbstractQueue(非阻塞队列),还有就是BlockingQueue(阻塞队列)),

使用场景:线程池和多线程并发处

队列家族关系图如下所示

image.png


以上就是一些概念,下面就开始写代码使用队列

其实和list,set一样主要就两个操作,添加 删除

但是根据不同的情况分为4组不同的API

  1. 抛出异常
  2. 不会抛出异常
  3. 阻塞等待
  4. 超时等待

方式

抛出异常

不会抛出异常,有返回值

阻塞等待(一直等待)

超时等待(规定时间内等待)

添加

add

offer

put()

offer(E e, long timeout, TimeUnit unit)

删除(移除)

remove

poll

take()

pollt(long timeout, TimeUnit unit)

检测队首(第一个进入队列的)元素

element

peek

阻塞不存在检测

阻塞不存在检测


创建阻塞队列

通过源码发现阻塞队列有一个重写方法,参数为队列初始大小(必须填写),是否公平(默认是不公平,可以不写,如果为true则为公平)


//创建BlockingQueue的实现类ArrayBlockingQueue(一个数组形的阻塞队列) 
//第一个参数不是泛型 而是队列的大小(可以存放多少个元素)
//第二个参数表示是否公平,默认是不公平的,一般可以不用去指名
ArrayBlockingQueue arrayBlockingQueue=new ArrayBlockingQueue<>(5,false);


image.png


public ArrayBlockingQueue(int capacity) {
this(capacity, false);
}
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull =  lock.newCondition();
}


1 第一组(抛出异常) add remove

如果操作不成功则会抛出异常


//创建BlockingQueue的实现类ArrayBlockingQueue(一个数组形的阻塞队列) 
//第一个参数不是泛型 而是队列的大小(可以存放多少个元素)
//第二个参数表示是否公平,默认是不公平的,一般可以不用去指名
ArrayBlockingQueue arrayBlockingQueue=new ArrayBlockingQueue<>(5,false);
//添加 参数为添加的元素 返回类型为布尔值 成功返回true 不成功返回false
arrayBlockingQueue.add(1);
//移除
arrayBlockingQueue.remove()
//查看队首
arrayBlockingQueue.element()


添加:add()    

关于add查看源码发现,需要一个Object类型的参数,返回一个boolan值(true或false),成功为true,失败为false

package com.wyh.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
/**
 * @program: JUC
 * @description: JUC下的阻塞队列demo
 * @author: 魏一鹤
 * @createDate: 2022-02-20 19:45
 **/
public class BlockingQueueDemo1 {
public static void main(String[] args){
   //创建BlockingQueue的实现类ArrayBlockingQueue(一个数组形的阻塞队列)
        //第一个参数不是泛型 而是队列的大小(可以存放多少个元素)
        //第二个参数表示是否公平,默认是不公平的,一般可以不用去指名
        ArrayBlockingQueue arrayBlockingQueue=new ArrayBlockingQueue<>(5);
        //add添加方法 需要一个object型的参数 返回一个布尔值(成功为true,失败为false)
 //如果我们往队列里面添加元素的个数大于了创建队列的时候参数的大小,则会报错
//java.lang.IllegalStateException: Queue full)
 System.out.println(arrayBlockingQueue.add(1));
        System.out.println(arrayBlockingQueue.add(2));
        System.out.println(arrayBlockingQueue.add(3));
    }
}


true

true

true


注意:如果我们往队列里面添加元素的个数大于了创建队列的时候参数的大小,则会报错



package com.wyh.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
/**
 * @program: JUC
 * @description: JUC下的阻塞队列demo
 * @author: 魏一鹤
 * @createDate: 2022-02-20 19:45
 **/
public class BlockingQueueDemo1 {
public static void main(String[] args){
//创建BlockingQueue的实现类ArrayBlockingQueue(一个数组形的阻塞队列)
        //第一个参数不是泛型 而是队列的大小(可以存放多少个元素)
        //第二个参数表示是否公平,默认是不公平的,一般可以不用去指名
        ArrayBlockingQueue arrayBlockingQueue=new ArrayBlockingQueue<>(5);
//add添加方法 需要一个object型的参数 返回一个布尔值(成功为true,失败为false)
        //如果我们往队列里面添加元素的个数大于了创建队列的时候参数的大小,则会报错
//java.lang.IllegalStateException: Queue full)
        System.out.println(arrayBlockingQueue.add(1));
        System.out.println(arrayBlockingQueue.add(2));
        System.out.println(arrayBlockingQueue.add(3));
        System.out.println(arrayBlockingQueue.add(4));
        System.out.println(arrayBlockingQueue.add(5));
        System.out.println(arrayBlockingQueue.add(6));
    }
}


package com.wyh.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
/**
 * @program: JUC
 * @description: JUC下的阻塞队列demo四组API 第一组抛出异常
 * @author: 魏一鹤
 * @createDate: 2022-02-20 19:45
 **/
//阻塞队列四组API:第一组抛出异常
public class BlockingQueueDemo1 {
public static void main(String[] args){
test1();
    }
public static void test1(){
//创建BlockingQueue的实现类ArrayBlockingQueue(一个数组形的阻塞队列)
        //第一个参数不是泛型 而是队列的大小(可以存放多少个元素)
        //第二个参数表示是否公平,默认是不公平的,一般可以不用去指名
        ArrayBlockingQueue arrayBlockingQueue=new ArrayBlockingQueue<>(3);
//add添加方法 需要一个object型的参数 返回一个布尔值(成功为true,失败为false)
        //如果我们往队列里面添加元素的个数大于了创建队列的时候参数的大小,队列已经满了还要添加,则会报错
        //java.lang.IllegalStateException: Queue full) 队列已满
        System.out.println(arrayBlockingQueue.add(1));
        System.out.println(arrayBlockingQueue.add(2));
        System.out.println(arrayBlockingQueue.add(3));
//循环打印下标 使用 for i 循环
        for (int i = 0; i < arrayBlockingQueue.size(); i++)
            System.out.println(i);
//循环打印arrayBlockingQueue中的元素 使用foreach循环
        for (Object o : arrayBlockingQueue) {
            System.out.println(o);
        }
    }
}


true

true

true

0

1

2

1

2

3


删除:remove()  

    remove方法没有参数,返回类类型是一个E,E就是它弹出来的那个元素,它是一个往外弹的过程,遵循FIFO(先进先出),如果进入先后顺序是1,2,3那么出去先后顺序也是1,2,3


package com.wyh.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
/**
 * @program: JUC
 * @description: JUC下的阻塞队列demo四组API 第一组抛出异常
 * @author: 魏一鹤
 * @createDate: 2022-02-20 19:45
 **/
public class BlockingQueueDemo1 {
public static void main(String[] args){
test1();
    }
    //第一组 抛出异常
public static void test1(){
//创建BlockingQueue的实现类ArrayBlockingQueue(一个数组形的阻塞队列)
        //第一个参数不是泛型 而是队列的大小(可以存放多少个元素)
        //第二个参数表示是否公平,默认是不公平的,一般可以不用去指名
        ArrayBlockingQueue arrayBlockingQueue=new ArrayBlockingQueue<>(3);
//add添加方法 需要一个object型的参数 返回一个布尔值(成功为true,失败为false)
        //如果队列已经满了还要添加,则会报错
        //java.lang.IllegalStateException: Queue full) 队列已满 抛出异常
        System.out.println(arrayBlockingQueue.add(1));
        System.out.println(arrayBlockingQueue.add(2));
        System.out.println(arrayBlockingQueue.add(3));
//分隔符 方便观看
        System.out.println("-------------------------------");
 //根据FIFO先进先出规格 弹出先进去的三个元素
        System.out.println(arrayBlockingQueue.remove()); 
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
    }
}
目录
相关文章
|
监控 负载均衡 算法
构建高效微服务架构的五大核心组件
【4月更文挑战第6天】随着现代业务需求的多样化和复杂性增加,传统的单体应用已无法满足快速迭代与灵活部署的需求。微服务架构应运而生,以其高度模块化、独立部署和可伸缩性成为企业转型的关键。本文聚焦于构建高效微服务架构的核心组件,从服务发现、配置管理、负载均衡、容错处理到服务监控五个方面进行深入剖析,旨在提供一套全面的技术指南以支持后端开发的最佳实践。
|
5月前
|
消息中间件 架构师 Kafka
【架构师】如何做技术选型?
技术选型无绝对优劣,关键在于“更合适”。需综合评估功能满足度、可扩展性、安全性、性能等非功能性需求,同时考量使用人数、社区活跃度、迭代速度、学习与维护成本,以及与现有技术体系的匹配度,权衡利弊后做出最优选择。
236 4
|
NoSQL 关系型数据库 MySQL
如何向mongoDB中添加新的字段附代码(全)
关于MongoDB更多的知识点可看我之前这篇文章: MongoDB框架零基础入门本身MongoDB的连接就和Mysql的数据库一样 Mysql连接方式:mysql -u -root -p(标准模式下) MongoDB类似:mongo -u root -p之所以要增加字段值 一般都是python web框架中,在form表单内增加了一个字段值写入数据库(只有最新的数据才有这个字段值) 之前数据没有的字段值只能通过数据库添加 具体添加方式可以通过数据库内或者脚本一键添加(两种方式都差不多)在数据库内增加字段值
908 0
|
24天前
|
人工智能 NoSQL IDE
Studio 3T 2026.5 发布 - MongoDB 的终极 GUI、IDE 和 客户端
Studio 3T 2026.5 (macOS, Linux, Windows) - MongoDB 的终极 GUI、IDE 和 客户端
133 1
|
Linux
npm install 报错ERESOLVE unable to resolve dependency tree
npm install 报错ERESOLVE unable to resolve dependency tree
359 0
|
8月前
|
存储 Java
Java LocalDateTime与hutool DateUtil实现秒转换为时分秒格式化展示。
注意:以上代码示例仅适合于处理小于24小时内(86400s) 总积 因 LocalDateTime 和 Local Time 不支持超过24小时表达而 huo tool示例虽然理论上支持但未考虑超过24小时情况下可能出现负值等异常情况处理细节需用户自行添加相关逻辑以确保正确性.
504 7
|
12月前
|
安全 Java
【Java并发】【ArrayBlockingQueue】适合初学体质的ArrayBlockingQueue入门
什么是ArrayBlockingQueue ArrayBlockingQueue是 Java 并发编程中一个基于数组实现的有界阻塞队列,属于 java.util.concurrent 包,实现了 Bl...
311 6
【Java并发】【ArrayBlockingQueue】适合初学体质的ArrayBlockingQueue入门
|
存储 监控 Java
JAVA线程池有哪些队列? 以及它们的适用场景案例
不同的线程池队列有着各自的特点和适用场景,在实际使用线程池时,需要根据具体的业务需求、系统资源状况以及对任务执行顺序、响应时间等方面的要求,合理选择相应的队列来构建线程池,以实现高效的任务处理。
861 12
|
Java 数据库连接 Android开发
Java中的内存泄漏及其排查方法
Java中的内存泄漏及其排查方法

热门文章

最新文章