多线程学习十九:生产者消费者

2023-10-29

异步模式之生产者/消费者

定义
与前面的保护性暂停中的 GuardObject 不同,不需要产生结果和消费结果的线程一一对应
消费队列可以用来平衡生产和消费的线程资源
生产者仅负责产生结果数据,不关心数据该如何处理,而消费者专心处理结果数据
消息队列是有容量限制的,满时不会再加入数据,空时不会再消耗数据
JDK 中各种阻塞队列,采用的就是这种模式
在这里插入图片描述
消息类

public class Message {
    private int id;
    private Object message;
    public Message(int id, Object message) {
        this.id = id;
        this.message = message;
    }
    public int getId() {
        return id;
    }
    public Object getMessage() {
        return message;
    }
}

消息队列

public class MessageQueue {
    private LinkedList<Message> queue;
    private int capacity;
    public MessageQueue(int capacity) {
        this.capacity = capacity;
        queue = new LinkedList<>();
    }
    public Message consume() {
        synchronized (queue) {
            while (queue.isEmpty()) {
                log.debug("没货了, wait");
                try {
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Message message = queue.removeFirst(); //从队列头部获取消息
            queue.notifyAll(); //告诉正在等待的生产这线程,有空间了可以存数据
            return message;
        }
    }
    public void put(Message message) {
        synchronized (queue) {
            while (queue.size() == capacity) {
                log.debug("库存已达上限, wait");
                try {
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            queue.addLast(message);
            queue.notifyAll(); //告诉正在等待的消费线程,去消费
        }
    }

}

测试

public class Test {
    public static void main(String[] args) {
        MessageQueue messageQueue = new MessageQueue(2);
        // 4 个生产者线程, 下载任务
        for (int i = 0; i < 4; i++) {
            int id = i;
            new Thread(() -> {
                try {
                    //log.debug("download...");
                    List<String> response = Downloader.download();
                            log.debug("try put message({})", id);
                    messageQueue.put(new Message(id, response));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }, "生产者" + i).start();
        }
        // 1 个消费者线程, 处理结果
        new Thread(() -> {
            while (true) {
                Message message = messageQueue.consume();
                List<String> response = (List<String>) message.getMessage();
                log.debug("consume message({}): [{}] lines", message.getId(), response.size());
            }
        }, "消费者").start();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多线程学习十九:生产者消费者 的相关文章

  • 使用 JPA/ORM 生成数据库模式是一个坏主意吗?

    Salve Part of 另一个问题 答案 https stackoverflow com questions 7595578关于 SO 以及其他声称相同的声明 如果您通过 JPA 更新数据库架构 但通常不是一个好的做法 您是否真的不应该
  • 使用 spring security 找不到 AuthenticationProvider

    我一直在尝试使用 x509 证书通过 LDAP 对用户进行身份验证 但似乎无法正常工作 我声明了一个身份验证提供程序 但仍然抛出错误 提示没有提供程序 这是我的调试输出 INFO Initiating Jersey application
  • java“类文件包含错误的类”错误

    我正在尝试制作一个控制台应用程序来测试我的网络服务 我成功部署了一个网络服务http localhost 8080 WS myWS http localhost 8080 WS myWS我用 wsimport 制作了代理类 wsimport
  • 为什么这不会导致 NullPointerException?

    public class Null public static void greet System out println Hello world public static void main String args Null null
  • java中main的返回类型

    我想知道为什么java中main方法只有void返回类型 public static void main String args 为什么main方法除了void之外没有其他返回类型 Thanks 简短的回答是 因为这就是语言规范 http
  • MAC OS 的 java.awt.Robot 类中出现无头环境错误

    我正在尝试使用 JavaFX 应用程序捕获屏幕截图Robot class 这是我在我的应用程序中使用的代码 Rectangle screenBounds new Rectangle Screen getPrimary getBounds g
  • 使用 eclipse 配置mockito 时出现问题。给出错误:java.lang.verifyError

    当我将我的mockito库添加到类路径中 并使用一个简单的mockito示例进行测试时 我尝试使用模拟对象为函数add返回错误的值 我得到java lang verifyerror 以下是用于测试的代码 后面是 logcat Test pu
  • Ubuntu 的打包 - Web 应用程序

    Web 应用程序没有与 C 或类似文件不同的 make 文件 但是 它需要放置在特定的目录中 例如 var www 我是 Linux 打包新手 所以我的问题是 如何将我的应用程序打包到 deb 中 以便在安装时将其放入 etc myprog
  • 在Java程序中计算zip文件的md5哈希值

    我有一个 zip 文件 在我的 Java 代码中我想计算 zip 文件的 md5 哈希值 有没有我可以用于此目的的 java 库 一些例子将非常感激 谢谢 几周前我通过这篇文章做到了这一点 http www javalobby org ja
  • 我们可以用java定制一个垃圾收集器吗?

    我们知道java的垃圾收集器是一个低优先级线程 在java中我们可以创建任何具有高优先级的线程 那么是否有可能拥有我们自己定制的具有可变优先级的垃圾收集器线程 我们可以根据内存管理的级别进行设置 有人尝试过吗 如果是的话 您能分享一些关于如
  • Java中如何限制文件大小

    我正在我的应用程序中创建一个文件 并继续向该文件中写入一些内容 但是当我的文件达到一定大小 比如说 100 行 后 我想删除第一行并将新行写入底部 要求是我的文件应该受到限制 但它应该保留我写入文件的最新内容 请告诉我在Java中是否可行
  • 如何检测java控制台中而不是GUI中的箭头键? [复制]

    这个问题在这里已经有答案了 我正在编写一个应用程序 我需要检测其中的箭头键 C 有getch 函数 我们想要获取输入 然后添加对 ASCII 值的检查 我们如何检测输入箭头键 谢谢 我写了一个Java类原始控制台输入 http www so
  • 从 SQL 语句中检索元数据(表名)

    我使用的是 Visual Studio 2008 我创建了一个 Winforms 应用程序 并且尝试从 SQL 语句中提取表名 con new SqlConnection connString String queryString Sele
  • Web服务连接超时和请求超时之间的区别

    WebClientTestService service new WebClientTestService int connectionTimeOutInMs 5000 Map
  • JTable中动态加载大量数据

    这是我的问题 我目前有一个 JTable 其中包含 5 000 到超过 200 000 行 你知道我要说什么了 数据已经加载到内存中了 这不是问题 但是如何 我可以创建一个高效的 JTable 以便它只加载以下行 是可见的 并且任何事件仅作
  • 如何在jpa中共享EntityManagerFactory

    我是 jpa 的新手 这是场景 我正在开发一个 Web 应用程序 其中 多个用户可以登录 当 user1 注销时 我正在使用下面的代码 public static void closeEntityManagerFactory if enti
  • Admob - 没有广告可显示

    你好 我尝试制作一些在 Android 手机上显示广告的示例程序 并尝试在 v2 2 的模拟器上测试它 代码中的一切似乎都很好 但调试器中的 AdListener 表示 响应消息为零或空 onFailedToReceiveAd 没有广告可显
  • 如何手动添加Android Studio依赖

    我多次尝试向我的项目添加依赖项 但每次都会出现错误 我想添加它们的依赖项是 de hdodenhof circleimageview 1 3 0 and com github bumptech glide glide 3 6 1 所以我想下
  • 在 Vavr 中结合任一者?

    我有几个Vavr https www vavr io Either https www vavr io vavr docs either的 我想调用一个函数Right每个 Either 的值 例如 Either
  • 生成签名和加密的 JWT

    我正在尝试使用生成签名和加密的 JWT 令牌雨云智威汤逊 http connect2id com products nimbus jose jwt private void generateToken throws JOSEExceptio

随机推荐

  • allegro设置禁止铺铜区的方法

    allegro设置禁止铺铜区的方法 Cadence Allegro 16 6 关于shape分割的一种方法 Allegro 铺铜设置 使用Shape Keepout设置禁止铺铜区 操作方法是Setup Areas Shape Keepout
  • 数据可视化python,绘制饼图,代码和解析

    饼图样式 使用matplotlib pyplot pie绘制 代码描述 import matplotlib pyplot as plt import pandas as pd 定义饼状图的标签 标签是列表 timeData pd read
  • Leetcode刷题(14. 最长公共前缀)

    Leetcode刷题 14 最长公共前缀 一 题目 二 代码 C 三 提交记录 四 备注 一 题目 编写一个函数来查找字符串数组中的最长公共前缀 如果不存在公共前缀 返回空字符串 示例 1 输入 flower flow flight 输出
  • 延长线段ab到c的画法有几种_垂直与平行的画法

    点击蓝字关注我们 垂直与平行的画法 现在中考对作图要求越来越高 作图是对我们应用数学基本定理 性质以及动手能力的一种考察 问题的关键在于学生平时忽视了定理 性质的重要性 甚至初三念完了书还是新的 通过作图 对定理和性质进行理解记忆 问题1
  • 使用Python爬取不同类别的豆瓣电影简介

    使用Python爬取不同类别的豆瓣电影简介 之前做过一点文本分类的工作 从豆瓣上爬取了不同类别的数千条电影的简介 爬取目标 我们爬取的目标是 豆瓣影视 打开豆瓣网 随便点击一部电影 即可看到电影的介绍 评论等信息 我们需要爬取的是电影的简介
  • sed与awk读书笔记[sed篇]

    简介 个人基础及笔记重点 sed基础 常用参数包括 寻址包括 常用命令包括 标志flags 正则表达式 sed高级这一章要详细讲解要不迷惑性太大举例 N命令 D命令 跳转命令aba 跳转命令ata hHgGx利用保持空间的命令 熟悉例子 最
  • Idea工具的使用

    文章目录 一 IDEA的使用 二 IDEA工具的快捷键以及一些简单的设置 1 字体设置 2 快速生成main方法 psvm 3 快速生成System out println sout 4 注意 IEDA是自动保存 不需要ctrl s 5 删
  • Python+Opencv 提取图片中某种颜色组成的图形

    主要目标识别图中红色的裂缝 尝试了几种不同的方法 最后发现比较每一点的RGB差值可以很好的解决这个问题 也就是提取图片中的红色相关信息 处理结果如下 实现的代码如下 注意opencv读入的图片通道顺序是bgr import cv2 impo
  • AWG线规对照表

    AWG American Wire Gauge 是美国电线标准的简称 AWG值是导线直径 以英寸计 的单位 其中 4 0表示0000 3 0表示000 2 0表示00 1 0表示0 例如 常用的电话线直径为26AWG 约为0 4mm 下表是
  • 停更一次博客

    明天微机原理复习 下周补两次博客
  • scala 的模式匹配与类型系统

    主要内容 1 scala模式匹配 2 scala类型系统 scala模式匹配 scala中的模式匹配与java中的switch case很类似 但是不同的是java中switch case只能匹配值 而scala模式匹配更强大 还可以对类型
  • execjs._exceptions.ProcessExitedWithNonZeroStatus

    报错如下图 提示我292的换行符有问题 刚开始我以为是我服务器的nodejs环境没有配好 就忽略了换行错误 后面发现nodejs已经配置好了 才转过来正视这个问题 在gitlab的textview里发现了端倪 在pycharm里面根本发现不
  • 三路红外arduino循迹小车(两驱-----黑线循迹)

    原理 红外传感器检测到黑线 红外光被吸收 其对于的led将不亮 反之无黑线 红外光被反射接收 点亮led 源代码是我借鉴他人加以修改的 代码也很简单 缺点就是跑不快 一旦快了容易冲出巡线轨迹 define STOP 0 define FOR
  • SpringBoot+Netty+WebSocket 实现消息推送

    关于Netty Netty 是一个利用 Java 的高级网络的能力 隐藏其背后的复杂性而提供一个易于使用的 API 的客户端 服务器框架 Maven依赖
  • Zotero使用分享(一)——导入文献、管理文献、引用文献

    Zotero使用分享 一 导入文献 管理文献 引用文献 0 为什么要用文献管理工具 1 Zotero是什么 2 安装 3 添加资源到Zotero 3 1 通过文献DOI导入 3 2 从剪贴板中导入 3 3 利用EndNote导入 3 4 用
  • BindingException: Invalid bound statement (not found)

    org apache ibatis binding BindingException Invalid bound statement not found com UserInfoMapper listByRole 报错描述 程序一直可以正常
  • NTSC、PAL、SECAM三大制式简介

    NTSC PAL SECAM三大制式简介 NTSC PAL和SECAM是全球三大主要的电视广播制式 这三种制式是不能互相兼容的 例如在PAL制式的电视上播放NTSC的视频 则影像画面将不能正常显示 下面分别对这三种制式进行简要介绍 NTSC
  • Deeplabcut----(1)新建自己的训练(单只动物)

    Deeplabcut新建自己的训练 本教程最后使用Autodl云平台跑代码 本地电脑上只是进行数据标注 建议直接新建多动物训练 比单动物的项目能干的事多 也能对单动物进行预测 个人使用感觉还是mmpose预测新视频和图片的正确率更高 整个文
  • 阿里云服务器安装及部署canal

    阿里云服务器安装及部署canal 1 环境部署 1 1 mysql开启binlog模式 1 查看当前mysql是否开启binlog模式 SHOW VARIABLES LIKE log bin 如果log bin的值为OFF是未开启 为ON是
  • 多线程学习十九:生产者消费者

    异步模式之生产者 消费者 定义 与前面的保护性暂停中的 GuardObject 不同 不需要产生结果和消费结果的线程一一对应 消费队列可以用来平衡生产和消费的线程资源 生产者仅负责产生结果数据 不关心数据该如何处理 而消费者专心处理结果数据