JUC并发编程_阻塞队列 BlockingQueue

news2024/9/24 13:31:23

JUC并发编程_阻塞队列 BlockingQueue

    • 一、基本概念
    • 二、主要特性
    • 三、常用方法
    • 四、实现类
      • ArrayBlockingQueue
      • LinkedBlockingQueue
      • PriorityBlockingQueue
      • SynchronousQueue
    • 五、使用场景
    • 六、注意事项

一、基本概念

阻塞队列是一种特殊的队列,它除了支持普通队列的插入(put/offer)和移除(take/poll)操作外,还支持两个附加的阻塞操作:

当队列满时,如果线程尝试向队列中添加元素,该线程将被阻塞,直到队列中有空间可用。
当队列空时,如果线程尝试从队列中移除元素,该线程将被阻塞,直到队列中有元素可取。

二、主要特性

线程安全:阻塞队列是线程安全的,多个线程可以并发访问它而不会发生冲突。
生产者-消费者模式:阻塞队列支持生产者-消费者模式,即生产者向队列中添加元素,消费者从队列中取出元素。
阻塞等待:通过阻塞等待机制,阻塞队列能够自动平衡生产者和消费者的速度差异,防止生产者过快导致队列溢出,或消费者过慢导致队列空置。

三、常用方法

put(E e):向队列中添加元素,如果队列已满则阻塞等待。
take():从队列中取元素,如果队列为空则阻塞等待。
boolean offer(E e, long timeout, TimeUnit unit):向队列中添加元素,如果队列已满,则等待指定的时间。
poll(long timeout, TimeUnit unit):从队列中取元素,如果队列为空则等待指定的时间。

四、实现类

Java中常用的阻塞队列的实现类:

ArrayBlockingQueue

基于数组的有界阻塞队列,按照先进先出(FIFO)的原则对元素进行排序。

// 指定容量为 10 的 ArrayBlockingQueue
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);

LinkedBlockingQueue

基于链表的无界阻塞队列(在指定容量时也可以作为有界队列),按照先进先出的顺序进行排序。

// 指定容量为 10 的 LinkedBlockingQueue
BlockingQueue<Integer> queue1 = new LinkedBlockingQueue<>(10);
// 无界阻塞队列
BlockingQueue<Integer> queue2 = new LinkedBlockingQueue<>();

PriorityBlockingQueue

支持优先级的无界阻塞队列,根据元素的优先级顺序进行排序。

SynchronousQueue

同步队列,不存储元素(容量为0),每次插入操作必须等待另一个线程的移除操作,每次移除操作必须等待另一个线程的插入操作。

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

public class SynchronousQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new SynchronousQueue<>(); //同步队列

        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+" put 1");
                blockingQueue.put("1");
                System.out.println(Thread.currentThread().getName()+" put 2");
                blockingQueue.put("2");
                System.out.println(Thread.currentThread().getName()+" put 3");
                blockingQueue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        },"T1").start();

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

    }
}

在这里插入图片描述

五、使用场景

线程池:Java中的线程池使用了阻塞队列来管理任务队列,当线程池中的线程数达到最大值时,新的任务会被放入阻塞队列中等待执行。
生产者-消费者模式:阻塞队列可以非常方便地实现生产者-消费者模式,生产者向队列中添加数据,消费者从队列中取出数据。
消息队列:阻塞队列可以用于实现消息队列,如Java消息服务(JMS)中的队列和主题就是基于阻塞队列实现的。
多线程协作:阻塞队列可以用于多线程之间的协作,通过阻塞等待机制实现线程间的同步和协调。

六、注意事项

容量设置:阻塞队列的容量需要根据实际情况进行设置,过小会导致队列溢出,过大会浪费内存资源。
阻塞方法:put()和take()方法是阻塞的,需要在多线程环境下使用,否则会导致线程阻塞。
公平性非公平性:某些阻塞队列实现(如ArrayBlockingQueue)支持公平锁和非公平锁,可以根据需要选择合适的锁策略。

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

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

相关文章

电动车车牌识别系统源码分享

电动车车牌识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

VUE-CLI配置全局SCSS变量

一.引入node-sass和sass-loader依赖 npm install --save-dev sass-loader node-sass 二. 在项目根目录中创建一个scss变量文件&#xff0c;比如constant.scss&#xff1a; 三.在vue.config.js文件中引入这个变量文件&#xff1a; // vue.config.js module.exports {css: {l…

艾体宝产品丨无需代码开发!Redis数据集成助你轻松优化数据库

我们不仅致力于加速应用程序的构建过程&#xff0c;更专注于助力您达成最终目标——实现应用的高效运行。因此&#xff0c;我们欣然宣布&#xff0c;Redis 数据集成&#xff08;Redis Data Integration&#xff0c;RDI&#xff09;(https://redis.io/data-integration/) 已经正…

自动化学习1:pytest自动化框架的基本用法:注意事项/断言assert/测试结果分析

一.注意事项&#xff1a; ①创建test开头的文件&#xff08;test_&#xff09;/类/函数或方法 ②pytest中以每一个函数或方法&#xff0c;作为用例 ③pytest启动方式&#xff1a;pytest def test01(): # 函数&#xff08;写在类外边是函数&#xff09;passclass Test:def t…

【机器学习】决策树算法

目录 算法引入 基尼系数&#xff1a; 决策树算法概述 决策树的关键概念 决策树的构建 代码实现 1. 定义决策树节点 2. 计算信息增益 3. 选择最佳分割特征 4. 构建决策树 5. 决策树预测 决策树的评估指标&#xff1a; 决策树的优缺点 优点&#xff1a; 缺点&…

Mitsuba 渲染基础

Mitsuba 渲染基础 0. Abstract1. 安装 Mitsuba21.1 下载 Mitsuba2 源码1.2 选择后端 (variants)1.3 编译 2. [Mitsuba2PointCloudRenderer](https://github.com/tolgabirdal/Mitsuba2PointCloudRenderer)2.1 Mitsuba2 渲染 XML2.2 Scene 场景的 XML 文件格式2.2.1 chair.npy to…

哪种电容笔更好用?2024精选推荐五款黄金畅销平替电容笔!

在当今信息化高速发展的时代&#xff0c;电容笔已成为众多电子设备用户不可或缺的重要配件。无论是专业的绘画创作者&#xff0c;还是日常学习、办公的人群&#xff0c;都对电容笔有着广泛的需求。可是市面上的品牌很多&#xff0c;到底哪种电容笔更好用呢&#xff1f;大家别担…

基于TCP协议的网络通信

TCP即传输控制协议&#xff0c;基于TCP协议的网络通信总是面向连接的&#xff0c;在通信过程中需要进行“三次握手&#xff0c;四次挥手”&#xff0c;这是众所周知的&#xff0c;所以这里不过多赘述。我们都知道TCP协议传输数据比较稳定&#xff0c;那么为什么稳定&#xff0c…

【Windows 同时安装 MySQL5 和 MySQL8 - 详细图文教程】

卸载 MySQL 参考文章&#xff1a; 完美解决Mysql彻底删除并重装_怎么找到mysql并卸载-CSDN博客使用命令卸载mysql_卸载mysql服务命令-CSDN博客 先管理员方式打开 cmd &#xff0c;切换到 MySQL 安装目录的 bin 文件夹下&#xff0c;执行如下命令&#xff0c;删除 MySQL 服务mys…

基于DPU的OpenStack裸金属服务快速部署及存储解决方案

1 方案背景和挑战 Openstack作为开源云计算领域的领军项目&#xff0c;凭借其强大的功能、灵活的架构以及活跃的社区支持&#xff0c;在全球范围内得到了广泛的采用。通过Openstack&#xff0c;企业和云服务提供商可以更加高效地管理和利用计算资源、存储资源和网络资源&#…

秋招面试准备:《小米2024数字芯片岗面试题》

在数字芯片设计的浪潮中&#xff0c;验证工程师的角色愈发重要。他们如同守门人&#xff0c;确保每一块芯片在投入市场前都能稳定、高效地运行。小米&#xff0c;作为全球知名的智能设备制造商&#xff0c;对数字芯片岗位的人才选拔尤为严格。 本文分享《小米2024数字芯片岗面…

Cat2Bug-Platform报告功能介绍

报告 报告是对团队、项目、测试用例、缺陷、交付物等工作管理做出的总结性报表&#xff0c;目前可通过OPEN API方式创建。 报告列表 报告列表中展示了已经提交的报表信息&#xff0c;点击某一个报告后可查看报告详情&#xff0c;报告可通过markdown格式展示&#xff0c;如下…

Java List初始化的六种方式

在日常的开发中,List作为我们常用的一种数据结构,那么有谁了解过在Java中如何对一个List进行初始化操作。在这些初始化操作中又有哪些遇到的坑呢? 1、常规方式 List<String> languageList = new ArrayList<>(); languageList.add("Java"); language…

C#使用实体类Entity Framework Core操作mysql入门:从数据库反向生成模型

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

如何构建出更好的大模型RAG系统?

ChatGPT爆火之后&#xff0c;以ChatPDF为首的产品组合掀起了知识库问答的热潮。 在过去一整年中&#xff0c;大多数人都在完成RAG系统到高级RAG系统的迭代升级。但是技术发展是迅速的&#xff0c;如何深入了解RAG的发展&#xff0c;做出更好的RAG系统&#xff0c;其实还是非常…

32岁前端干了8年,是继续做前端开发,还是转其它工作_ui设计师转开发

前端发展有瓶颈&#xff0c;变来变去都是那一套&#xff0c;只是换了框架换了环境。换了框架后又得去学习&#xff0c;虽然很快上手&#xff0c;但是那些刚毕业的也很快上手了&#xff0c;入门门槛越来越低&#xff0c;想转行或继续卷&#xff0c;该如何破圈? 这是一位网友的自…

使用SBP打AssetBundle时脚本引用丢失

1&#xff09;使用SBP打AssetBundle时脚本引用丢失 2&#xff09;在UE 5.3中连接Power节点为何10的3次幂等于1009 3&#xff09;如何在Widget中倾斜一张纹理贴图 4&#xff09;如何在打开关卡蓝图时更改游戏模式 这是第401篇UWA技术知识分享的推送&#xff0c;精选了UWA社区的热…

uni-app快速入门

目录 一、什么是 uni-app二、快速创建 uni-app 项目1.创建 uni-app2.运行 uni-app 三、uni-app 相对传统 H5 的变化1.网络模型的变化2.文件类型变化3.文件内代码架构的变化4.外部文件引用方式变化5.组件/标签的变化6.js的变化&#xff08;1&#xff09;运行环境从浏览器变成v8引…

MCU自动测量单元采集振弦式应变计测值的过程

振弦式应变计是一种广泛应用于土木工程、地质勘探等领域的高精度传感器&#xff0c;用于测量结构的应变变化。近年来&#xff0c;随着微控制器单元(MCU)的发展&#xff0c;自动化测量技术得到了极大的提升&#xff0c;使得振弦式应变计的测值采集更加高效和精确。本文将详细介绍…

关于 mybatis-plus-boot-starter 与 mybatis-spring-boot-starter 的错误

不是知道你是否 出现过这样的错误 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): 经过各种度娘&#xff0c;无非就是让你检查三种情况 情况一&#xff1a;mapper.xml没有按照传统的maven架构进行放置 情况二&#xff1a;mybatis的配置信…