了解Java的LinkedBlockingQueue

了解Java的LinkedBlockingQueue

LinkedBlockingQueue是一个基于链接节点的有界阻塞队列。它实现了BlockingQueue接口,可以在多线程环境中安全地进行插入、移除和检查操作。LinkedBlockingQueue的容量可以在创建时指定,如果未指定,则默认容量为Integer的最大值。

线程安全

LinkedBlockingQueue通过以下机制实现线程安全:

  1. 独占锁(ReentrantLock):队列内部使用两把不同的独占锁来管理入队和出队操作。入队操作和出队操作分别使用不同的锁,从而实现了入队和出队的并行操作,提高了性能。

  2. 条件变量(notEmpty和notFull)

    • notEmpty:用于等待队列不为空的条件。当消费者线程发现队列为空时,会在notEmpty上等待,直到有元素被生产者放入队列。
    • notFull:用于等待队列未满的条件。当生产者线程发现队列已满时,会在notFull上等待,直到有空间被消费者释放。
  3. 节点链接结构LinkedBlockingQueue使用链表节点来存储数据,每个节点包含一个数据元素和指向下一个节点的引用。入队操作会在链表的尾部插入新节点,出队操作会从链表的头部移除节点。

  4. 容量限制LinkedBlockingQueue可以通过构造函数指定容量,如果未指定则默认容量为Integer.MAX_VALUE。在插入元素时,如果队列已满,插入操作会被阻塞,直到有空间可用;在移除元素时,如果队列为空,移除操作会被阻塞,直到有元素可用。

通过上述机制,LinkedBlockingQueue能够在多线程环境中保证线程安全,同时在性能和资源利用率之间取得平衡。

使用方法

创建队列

可以通过指定容量来创建LinkedBlockingQueue

LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);

如果不指定容量,队列的默认容量为Integer.MAX_VALUE

LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();

插入元素

LinkedBlockingQueue提供了多种插入元素的方法:

  • put(E e):如果队列已满,则等待直到队列不再满。
  • offer(E e):如果队列已满,则返回false
  • offer(E e, long timeout, TimeUnit unit):在指定的时间内等待可用空间,如果超时则返回false
queue.put(1);
boolean success = queue.offer(2);
boolean successWithTimeout = queue.offer(3, 2, TimeUnit.SECONDS);

移除元素

LinkedBlockingQueue提供了多种移除元素的方法:

  • take():如果队列为空,则等待直到有元素可用。
  • poll():如果队列为空,则返回null
  • poll(long timeout, TimeUnit unit):在指定的时间内等待元素可用,如果超时则返回null
Integer item = queue.take();
Integer itemOrNull = queue.poll();
Integer itemOrNullWithTimeout = queue.poll(2, TimeUnit.SECONDS);

检查元素

LinkedBlockingQueue提供了检查元素的方法:

  • peek():返回队列头部的元素,但不移除它,如果队列为空,则返回null
Integer head = queue.peek();

应用场景

生产者-消费者模式

LinkedBlockingQueue非常适用于生产者-消费者模式。在这种模式中,生产者线程负责生产数据并将其放入队列中,消费者线程从队列中取出数据进行处理。LinkedBlockingQueue的阻塞特性可以有效地协调生产者和消费者的速度,避免数据丢失和资源浪费。

示例代码

class Producer implements Runnable {
    private final LinkedBlockingQueue<Integer> queue;

    public Producer(LinkedBlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                int item = produce();
                queue.put(item);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private int produce() {
        // 生产数据的逻辑
        return new Random().nextInt();
    }
}

class Consumer implements Runnable {
    private final LinkedBlockingQueue<Integer> queue;

    public Consumer(LinkedBlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                int item = queue.take();
                consume(item);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private void consume(int item) {
        // 消费数据的逻辑
    }
}

public class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);

        new Thread(producer).start();
        new Thread(consumer).start();
    }
}

任务调度

在任务调度系统中,可以使用LinkedBlockingQueue来管理任务队列。调度器线程将任务添加到队列中,工作线程从队列中获取任务并执行。这样可以实现任务的均衡分配和并发处理,提高系统的响应速度和处理能力。

示例代码

class TaskScheduler {
    private final LinkedBlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>();
    private final List<Thread> workers = new ArrayList<>();

    public TaskScheduler(int numberOfWorkers) {
        for (int i = 0; i < numberOfWorkers; i++) {
            workers.add(new Thread(new Worker(taskQueue)));
        }
        for (Thread worker : workers) {
            worker.start();
        }
    }

    public void schedule(Runnable task) throws InterruptedException {
        taskQueue.put(task);
    }

    private static class Worker implements Runnable {
        private final LinkedBlockingQueue<Runnable> taskQueue;

        public Worker(LinkedBlockingQueue<Runnable> taskQueue) {
            this.taskQueue = taskQueue;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    Runnable task = taskQueue.take();
                    task.run();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

参考链接

  • Baeldung: Java BlockingQueue
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI绘画stable diffusion 模型介绍及下载、使用方法,超全的新手入门教程建议收藏!

大家好&#xff0c;我是画画的小强 今天我将继续分享AI绘画Stable Diffusion的模型、参数含义等&#xff0c;分享给各位朋友一起学习。 一、模型 Stable difusion 模型就是所谓的大模型&#xff0c;用来控制整个画面的风格走势的。 打开webui页面&#xff0c;可以看到大模型…

安卓实现圆形按钮轮廓以及解决无法更改按钮颜色的问题

1.实现按钮轮廓 在drawable文件新建xml文件 <shape xmlns:android"http://schemas.android.com/apk/res/android"<!--实现圆形-->android:shape"oval"><!--指定内部的填充色--><solid android:color"#FFFFFF"/><!-…

Mongodb介绍及window环境安装

本文主要内容为nosql数据库-MongoDB介绍及window环境安装。 目录 什么是MongoDB&#xff1f; 主要特点 MongoDB 与Mysql对应 安装MongoDB 下载MongoDB 自定义安装 创建目录 配置环境变量 配置MongoDB服务 服务改为手动 启动与关闭 安装MongoDB Shell 下载安装包 …

高考分数限制下,选好专业还是选好学校?

高考分数限制下&#xff0c;选好专业还是选好学校&#xff1f; 高考作为每年一度的盛大考试&#xff0c;不仅关乎学生们的未来&#xff0c;更承载了家庭的期望。2004年高考刚刚结束&#xff0c;许多考生和家长已经开始为填报志愿而焦虑。选好学校和专业&#xff0c;直接关系到…

LogicFlow 学习笔记——8. LogicFlow 基础 事件 Event

事件 Event 当我们使用鼠标或其他方式与画布交互时&#xff0c;会触发对应的事件。通过监听这些事件&#xff0c;可以获取其在触发时所产生的数据&#xff0c;根据这些数据来实现需要的功能。详细可监听事件见事件API。 监听事件 lf实例上提供on方法支持监听事件。 lf.on(&…

【SCAU数据挖掘】数据挖掘期末总复习题库应用题及解析

1. 给定圆的半径为e &#xff0c;令 MinPts3&#xff0c;考虑下面两幅图。 &#xff08;1&#xff09;哪些对象是核心对象? m,p,o,r(因为这些核心对象在半径e的范围内都至少包含MinPts3个对象) &#xff08;2&#xff09;哪些对象是直接密度可达的? 对象q是…

2024年【通信安全员ABC证】最新解析及通信安全员ABC证模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 通信安全员ABC证最新解析是安全生产模拟考试一点通总题库中生成的一套通信安全员ABC证模拟试题&#xff0c;安全生产模拟考试一点通上通信安全员ABC证作业手机同步练习。2024年【通信安全员ABC证】最新解析及通信安全…

vuejs3 pinia持久化存储

pinia地址&#xff1a; 开始 | Pinia 插件地址&#xff1a; 快速开始 | pinia-plugin-persistedstate 先安装pinia npm install pinia 再安装插件 安装pinia后&#xff0c;再安装这个插件 npm i pinia-plugin-persistedstate 全局中引入持久化插件 在src目录下的main…

【ONE·基础算法 || 记忆化搜索】

总言 主要内容&#xff1a;编程题举例&#xff0c;熟悉理解记忆化搜索类题型&#xff08;对比递归、动态规划理解运用&#xff09;。             文章目录 总言1、记忆化搜索1.1、基本介绍1.2、细节理解&#xff08;记忆搜索化、递归、动态规划……&#xff09; 2、斐…

智源联合多所高校推出首个多任务长视频评测基准MLVU

当前&#xff0c;研究社区亟需全面可靠的长视频理解评估基准&#xff0c;以解决现有视频理解评测基准在视频长度不足、类型和任务单一等方面的局限性。因此&#xff0c;智源联合北邮、北大和浙大等多所高校提出首个多任务长视频理解评测基准MLVU&#xff08;A Comprehensive Be…

利用K8S技术栈打造个人私有云

1.三个节点&#xff1a;master&#xff0c;slave&#xff0c;client 在Kubernetes集群中&#xff0c;三个节点的职责分别如下&#xff1a; Master节点&#xff1a; docker&#xff1a;用于运行Docker容器。 etcd&#xff1a;一个分布式键值存储系统&#xff0c;用于保存Kuberne…

AI + 3D:用单个图像和文本提示创建可交互的3D世界

你是否曾经梦想过只需一张照片和一些简单的文字描述,就能立即进入一个生动的3D虚拟世界?今天,我们将介绍一个革命性的技术,它就像是一台神奇的3D场景制造机,能够根据你的想象快速构建出令人惊叹的虚拟空间。 一、技术概览 这项技术不仅仅是一个简单的图像到3D的转换工具…

PCB雕刻切割用德国自动换刀主轴SycoTec 4033 AC-ESD

随着电子行业的蓬勃发展&#xff0c;印刷电路板&#xff08;PCB&#xff09;的应用范围正在迅速扩大&#xff0c;涵盖了通信、计算机、消费电子等诸多领域。伴随着PCB的广泛应用&#xff0c;对PCB板切割加工技术的要求也日益严格。高速电主轴作为分板机的关键零部件之一&#x…

【vue3|第10期】Vue3中watchEffect详解

日期&#xff1a;2024年6月10日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

CSS详解

盒子模型&#xff08;box-sizing&#xff09; line-height与height CSS选择符和可继承属性 属性选择符&#xff1a; 示例&#xff1a;a[target"_blank"] { text-decoration: none; }&#xff08;选择所有target"_blank"的<a>元素&#xff09; /* 选…

63、上海大学:MSConvNet-多尺度卷积神经网络解码大鼠运动疲劳数据[攒劲的模型来喽]

1、介绍&#xff1a; 文章&#xff1a;<A multiscale convolutional neural network based on time-frequency features for decoding rat exercise fatigue LFP >&#xff0c;本文由上海大学于2024.4.8日发表于<Biomedical Signal Processing and Control >&…

【启明智显产品介绍】Model4 工业级HMI芯片详解系列专题(一):芯片性能

Model4 工业级HMI芯片详解系列专题&#xff08;一&#xff09;【芯片性能】 Model4系列工业级MPU是国产自主面向工业应用的RISC-V架构的应用级芯片&#xff0c;内置玄铁64bit RISC-V CPU C906&#xff0c;主频高达600MHz&#xff0c;算力约1380DMIPS。 Model4系列工业级MPU具…

App上架和推广前的准备

众所周知&#xff0c;App推广的第一步是上架各大应用下载市场&#xff0c;然后才是其他推广渠道。所以本文主要分两部分&#xff0c;第一部分主要介绍的是上架各大应用市场方面的准备&#xff0c;第二部分主要介绍的是其他渠道推广方面的准备。 一、App上架前的准备 1.1 上架…

演示:WPF开发的Diagram自动化流程图应用

一、目的&#xff1a;演示Diaram应用功能 二、预览 三、功能列表 功能模块 通用测试 流程图 仪器仪表 机器人 网络通信测试 PLC测试 轮毂生产线流程测试 图像处理 目标检测 绘图 思维导图 图表 流程图功能 模板管理 工程管理 模块许可管理 工具栏 开始 停止 删除 清除 …

任务3.8.3 利用RDD统计每日新增用户

任务目标 统计给定用户访问历史数据中&#xff0c;每日的新增用户数量。 数据准备 原始数据格式&#xff1a;每行包含两个字段&#xff0c;日期和用户名&#xff0c;以逗号分隔。示例数据&#xff1a;2024-05-01,mike 2024-05-01,alice 2024-05-01,brown ...解决方案 使用倒…