阻塞队列BlockingQueue

news2024/9/29 18:07:14

一、概念

阻塞队列:从名字可以看出,他也是队列的一种,那么他肯定是一个先进先出(FIFO)的数据结构。与普通队列不同的是,它支持两个附加操作,即阻塞添加阻塞删除方法。

如上图,线程1往阻塞队列中添加元素,而线程2从阻塞队列中移除元素。而在这一系列操作必须符合以下规定:

  • 阻塞添加:当阻塞队列是满时,往队列里添加元素的操作将被阻塞。

  • 阻塞移除:当阻塞队列是空时,从队列中获取元素/删除元素的操作将被阻塞。

阻塞队列的好处

阻塞队列不用手动控制什么时候该被阻塞,什么时候该被唤醒,简化了操作。

BlockingQueue的主要方法

二、分类

  • ArrayBlockingQueue:由数组结构组成的有界阻塞队列。

  • LinkedBlockingQueue:由链表结构组成的有界(但大小默认值为Integer.MAX_VALUE即2147483647)阻塞队列。

  • PriorityBlockingQueue:支持优先级排序的无界阻塞队列。

  • DelayQueue:使用优先级队列实现的延迟无界队列。

  • SynchronousQueue:不存储元素的阻塞队列,也即单个元素的队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。

  • LinkedTransferQueue:由链表结构组成的无界阻塞队列。

  • LinkedBlockingDeque:由链表结构组成的双向阻塞队列。

三、BlockingQueue的核心方法

方法类型

抛出异常

返回布尔

阻塞

超时

插入

add(E e)

offer(E e)

put(E e)

offer(E e,Time,TimeUnit)

移除

remove()

poll()

take()

poll(Time,TimeUnit)

队首

element()

peek()

  • 抛出异常是指当队列满时,再次插入会抛出异常(如果队列未满,插入返回值未true);

  • 返回布尔是指当队列满时,再次插入会返回false;

  • 阻塞是指当队列满时,再次插入会被阻塞,直到队列取出一个元素,才能插入。

  • 超时是指当一个时限过后,才会插入或者取出。

1、抛出异常组

  • 当阻塞队列满时,再往队列里add插入元素会抛IllegalStateException: Queue full

  • 当阻塞队列空时,再往队列里remove移除元素会抛NoSuchElementException

代码案例:

public class BlockingQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
        // 插入
        System.out.println("插入");
        System.out.println(blockingQueue.add("a"));
        System.out.println(blockingQueue.add("b"));
        System.out.println(blockingQueue.add("c"));
        // Exception in thread "main" java.lang.IllegalStateException: Queue full
//        blockingQueue.add("d");

        // 检查
        System.out.println("检查");
        System.out.println(blockingQueue.element());

        // 移除
        System.out.println("移除");
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        // Exception in thread "main" java.util.NoSuchElementException
//        System.out.println(blockingQueue.remove());

    }
}

2、返回布尔值组

  • offer插入方法,成功true,失败false

  • poll移除方法,成功返回出队列的元素,队列里面没有就返回null

代码案例:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
        // 插入
        System.out.println("插入");
        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        System.out.println(blockingQueue.offer("d"));

        // 检查
        System.out.println("检查");
        System.out.println(blockingQueue.peek());

        // 移除
        System.out.println("移除");
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());

        System.out.println("检查");
        System.out.println(blockingQueue.peek());

    }
}

输出结果:

插入
true
true
true
false
检查
a
移除
a
b
c
null
检查
null

3、阻塞和超时控制

阻塞

  • 当阻塞队列满时,生产者线程继续往队列里put元素,队列会一直阻塞生产线程直到put数据或者响应中断退出。

  • 当阻塞队列空时,消费者线程试图从队列里take元素,队列会一直阻塞消费者线程直到队列可用。

代码案例:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
        // 插入
        System.out.println("插入");
        blockingQueue.put("a");
        blockingQueue.put("a");
        blockingQueue.put("a");
        System.out.println("=======================");
        blockingQueue.put("a");

        // 移除
        System.out.println("移除");
        blockingQueue.take();
        blockingQueue.take();
        blockingQueue.take();
        blockingQueue.take();
    }
}

超时退出

  • 当阻塞队列满时,队列会阻塞生产者线程一定时间,超过限时后生产者线程会退出。

代码案例:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
        // 插入
        System.out.println("插入");
        System.out.println(blockingQueue.offer("a", 2, TimeUnit.SECONDS));
        System.out.println(blockingQueue.offer("a", 2, TimeUnit.SECONDS));
        System.out.println(blockingQueue.offer("a", 2, TimeUnit.SECONDS));
        System.out.println("=======================" + System.currentTimeMillis());
        System.out.println(blockingQueue.offer("a", 2, TimeUnit.SECONDS));
        System.out.println("=======================" + System.currentTimeMillis());

        // 移除
        System.out.println("移除");
        System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
        System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
        System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
        System.out.println("=======================" + System.currentTimeMillis());
        System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
        System.out.println("=======================" + System.currentTimeMillis());
    }
}

4、同步SynchronousQueue队列

SynchronousQueue:不存储元素的阻塞队列,也即单个元素的队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。

代码案例:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new SynchronousQueue<>();
        new Thread(() -> {
            try {
                System.out.println(Thread.currentThread().getName() + "\t put 1");
                blockingQueue.put("1");
                System.out.println(Thread.currentThread().getName() + "\t put 2");
                blockingQueue.put("2");
                System.out.println(Thread.currentThread().getName() + "\t put 3");
                blockingQueue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "AAA").start();

        new Thread(() -> {
            try {
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t" + blockingQueue.take());
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t" + blockingQueue.take());
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t" + blockingQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "BBB").start();
    }
}

输出结果:

AAA     put 1
BBB    1
AAA     put 2
BBB    2
AAA     put 3
BBB    3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/375031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年值得参加的数学建模竞赛介绍

数学建模竞赛&#xff1a;一次参与&#xff0c;终身受益 博主7年数学建模竞赛经验&#xff0c;历史获奖率百分之百。团队成员都是拿过全国一等奖的硕博&#xff0c;有需要数模竞赛帮助的可以私信我。 有同学咨询还有那些数学建模比赛可以参加&#xff0c;哪些含金量比较高&…

Qt图片定时滚动播放器+透明过渡动画

目录参考结构PicturePlay.promain.cppmyqlabel.h 自定义QLabelmyqlabel.cpp自定义QLabelpictureplay.hpictureplay.cpppictureplay.uistyle.qss效果源码参考 Qt图片浏览器 QT制作一个图片播放器 Qt中自适应的labelpixmap充满窗口后&#xff0c;无法缩小只能放大 Qt的动画类修改…

3 决策树及Python实现

1 主要思想 1.1 数据 1.2 训练和使用模型 训练&#xff1a;建立模型&#xff08;树&#xff09; 测试&#xff1a;使用模型&#xff08;树&#xff09; Weka演示ID3&#xff08;终端用户模式&#xff09; 双击weka.jar选择Explorer载入weather.arff选择trees–>ID3构建树…

简单易懂又非常牛逼的Spring源码解析,推断构造与bean的实例化

简单易懂又非常牛逼的Spring源码解析&#xff0c;推断构造与bean的实例化原理解析实例化bean的入口工厂方法实例化推断构造初次筛选二次筛选bean的实例化代码走读实例化bean的入口createBeanInstance方法内部的流程推断构造初次筛选二次筛选bean的实例化总结往期文章&#xff1…

十六、vue3.0之富文本编辑器的选择

在工作过程中我们会遇到很多的时候会使用到富文本编辑器,市场上流行的也是各种各样的,那么究竟如何选择呢,今天就给大家讲讲有哪一些,方便大家的选择。 一、TinyMCE TinyMCE 是富文本编辑器领域的头部玩家之一,主流富文本编辑器,功能非常全,你需要的大多数功能它都支持…

深力科电子-MachXO3系列 LCMXO3LF-1300C-5BG256C 控制和桥接FPGA器件

深力科电子-lattice莱迪斯MachXO3系列 LCMXO3LF-1300C-5BG256C 控制和桥接FPGA器件 &#xff0c;FPGA 现场可编程逻辑器件,小尺寸&#xff0c;高性能&#xff01;在工业领域&#xff0c;它可以用于网络控制器&#xff0c;PLC,网络边缘计算&#xff0c;机器视觉和工业机器人&…

万字解析 Linux 中 CPU 利用率是如何算出来的?

在线上服务器观察线上服务运行状态的时候&#xff0c;绝大多数人都是喜欢先用 top 命令看看当前系统的整体 cpu 利用率。例如&#xff0c;随手拿来的一台机器&#xff0c;top 命令显示的利用率信息如下 这个输出结果说简单也简单&#xff0c;说复杂也不是那么容易就能全部搞明白…

【java web篇】使用JDBC操作数据库

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

学习Java前,应该了解的这些知识(新手必学)

Java语言广泛应用于编写web应用程序、移动开发、安卓开发等&#xff0c;市场上对Java人才需求量很大&#xff0c;有数据显示&#xff0c;Java工程师的薪资待遇随着人才市场的需求逐步递增&#xff0c;由此可见&#xff0c;Java人才需求量呈现持续上升趋势&#xff0c;供不应求。…

LevelDB架构介绍以及读、写和压缩流程

LevelDB 基本介绍 是一个key/value存储&#xff0c;key值根据用户指定的comparator排序。 特性 keys 和 values 是任意的字节数组。数据按 key 值排序存储。调用者可以提供一个自定义的比较函数来重写排序顺序。提供基本的 Put(key,value)&#xff0c;Get(key)&#xff0c;…

企业电子招标采购源码之电子招标投标全流程!

随着各级政府部门的大力推进&#xff0c;以及国内互联网的建设&#xff0c;电子招投标已经逐渐成为国内主流的招标投标方式&#xff0c;但是依然有很多人对电子招投标的流程不够了解&#xff0c;在具体操作上存在困难。虽然各个交易平台的招标投标在线操作会略有不同&#xff0…

13-mvc框架原理与实现方式

1、mvc原理 # mvc 与框架## 1.mvc 是什么1. m:model,模型(即数据来源),主要是针对数据库操作 2. v:view,视图,html 页面。视图由一个一个模板构成(模板是视图的一个具体展现或载体,视图是模板的一个抽象) 3. c:controller,控制器,用于mv之间的数据交互## 2.最简单的 mvc 就是一…

Java+Swing+Mysql实现超市管理系统

一、系统介绍1.开发环境操作系统&#xff1a;Win10开发工具 &#xff1a;IDEA2018JDK版本&#xff1a;jdk1.8数据库&#xff1a;Mysql8.02.技术选型JavaSwingMysql3.功能模块4.系统功能1.系统登录登出管理员可以登录、退出系统2.商品信息管理管理员可以对商品信息进行查询、添加…

MapReduce小试牛刀

部署完hadoop单机版后&#xff0c;试下mapreduce是怎么分析处理数据的 Word Count Word Count 就是"词语统计"&#xff0c;这是 MapReduce 工作程序中最经典的一种。它的主要任务是对一个文本文件中的词语作归纳统计&#xff0c;统计出每个出现过的词语一共出现的次…

【云原生kubernetes】k8s 常用调度策略使用详解

一、前言 通过之前的学习&#xff0c;我们了解到k8s集群中最小工作单位是pod&#xff0c;对于k8s集群来说&#xff0c;一个pod的完整生命周期是由一系列调度策略来控制&#xff0c;这些调度策略具体是怎么工作的呢&#xff1f;本文将详细讨论下这个问题。 二、k8s调度策略简介…

K8S---Pod进阶资源限制以及探针

目录 一、Pod 进阶 1、资源限制 2、Pod 和 容器 的资源请求和限制&#xff1a; 3、CPU 资源单位 4、内存 资源单位 5、实例操作 5.1 示例1 5.2 示例2 6、重启策略&#xff08;restartPolicy&#xff09; 6.1 示例1 二、健康检查&#xff1a;又称为探针&#xff08;P…

华为OD机试题,用 Java 解【机器人走迷宫】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…

电动针阀流量控制和电气比例阀压力控制在液氮低温控制中的应用

摘要&#xff1a;为了解决室温至液氮温区温控系统中需要昂贵的低温电动阀门进行液氮介质流量调节的问题&#xff0c;本文提供了三种不同精度的液氮温区内的低温温度控制解决方案。解决方案的技术核心是通过采用电动针阀和电气比例阀在室温环境下来快速调节外部气源流量或压力大…

Nginx网站服务——编译安装、基于授权和客户端访问控制

文章目录一、Nginx概述1.1、Nginx的特点1.2、Nginx编译安装1.3、Nginx运行控制1.4、Nginx和Apache的区别二、编译安装Nginx服务的操作步骤2.1、关闭防火墙&#xff0c;将安装nginx所需软件包传到/opt目录下2.2、安装依赖包2.3、创建运行用户、组&#xff08;Nginx 服务程序默认…

【2023全网最全教程】从0到1开发自动化测试框架(建议收藏)

一、序言 随着项目版本的快速迭代、APP测试有以下几个特点&#xff1a; 首先&#xff0c;功能点多且细&#xff0c;测试工作量大&#xff0c;容易遗漏&#xff1b;其次&#xff0c;代码模块常改动&#xff0c;回归测试很频繁&#xff0c;测试重复低效&#xff1b;最后&#x…