【Java并发】生产者消费者模型 - 两线程交替打印1-100

2023-11-11

生产者消费者模型

以下是其中一种通过synchronize的实现:

import java.util.Queue;
import java.util.LinkedList;

public class ProducerAndConsumer {
    private final int MAX_LEN = 10;
    private Queue<Integer> queue = new LinkedList<>();

    class Producer extends Thread {
        @Override
        public void run() {
            producer();
        }

        private void producer() {
            // 循环限制:无限
            while (true) {
                // 加锁对象:queue
                synchronized (queue) {
                    // producer()的停止(暂停)条件
                    while (queue.size() == MAX_LEN) {
                        queue.notify();
                        System.out.println("当前队列满");
                        try {
                            queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.add(1);
                    queue.notify();
                    System.out.println("生产者生产一个任务,当前队列长度为: " + queue.size());
                    // 执行完休眠(停顿)500毫秒
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    class Consumer extends Thread {
        @Override
        public void run() {
            consumer();
        }

        private void consumer() {
            while (true) {
                synchronized (queue) {
                    while (queue.size() == 0) {
                        queue.notify();
                        System.out.println("当前队列空");
                        try {
                            queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.poll();
                    queue.notify();
                    System.out.println("消费者消费一条任务, 当前队列长度为: " + queue.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
     ProducerAndConsumer pc = new ProducerAndConsumer();
     Producer p = pc.new Producer();
     Consumer c = pc.new Consumer();
     p.start();
     c.start();
    }
}

两线程交替打印1-100

我们基于上面这种生产者消费者模型,重写成让两个线程交替打印1-100,

交替是绝对的,所以定义boolean state,每次打印完就翻转为false/true来实现交替。当state=false时,producer1不执行,当state=true,producer2不执行。

从1开始打印到100停止,我们定义一个int count=1,每次打印完count就让count+1。循环限制也不再是无限了,而是到count = 100时停止(while (count < 100) { … })。

public class printOneToHundred {
    private static volatile boolean state = true;
    private static volatile int count = 1;
    private static final Object lock = new Object();

    class Producer1 extends Thread {
        @Override
        public void run() {
            producer1();
        }

        private void producer1() {
            while (count < 100) {
                synchronized (lock) {
                    while (!state) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("线程1打印:" + count);
                    count++;
                    state = false;
                    lock.notify();
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    class Producer2 extends Thread {
        @Override
        public void run() {
            producer2();
        }

        private void producer2() {
            while (count < 100) {
                synchronized (lock) {
                    while (state) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("线程2打印:" + count);
                    count++;
                    state = true;
                    lock.notify();
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        printOneToHundred print = new printOneToHundred();
        Producer1 p = print.new Producer1();
        Producer2 c = print.new Producer2();
        p.start();
        c.start();
    }
}

输出:

线程1打印:1
线程2打印:2
线程1打印:3
线程2打印:4
线程1打印:5
线程2打印:6
线程1打印:7
线程2打印:8
线程1打印:9
线程2打印:10
线程1打印:11
线程2打印:12
线程1打印:13
线程2打印:14
线程1打印:15
线程2打印:16
线程1打印:17
线程2打印:18
线程1打印:19
线程2打印:20
线程1打印:21
线程2打印:22
线程1打印:23
线程2打印:24
线程1打印:25
线程2打印:26
线程1打印:27
线程2打印:28
线程1打印:29
线程2打印:30
线程1打印:31
线程2打印:32
线程1打印:33
线程2打印:34
线程1打印:35
线程2打印:36
线程1打印:37
线程2打印:38
线程1打印:39
线程2打印:40
线程1打印:41
线程2打印:42
线程1打印:43
线程2打印:44
线程1打印:45
线程2打印:46
线程1打印:47
线程2打印:48
线程1打印:49
线程2打印:50
线程1打印:51
线程2打印:52
线程1打印:53
线程2打印:54
线程1打印:55
线程2打印:56
线程1打印:57
线程2打印:58
线程1打印:59
线程2打印:60
线程1打印:61
线程2打印:62
线程1打印:63
线程2打印:64
线程1打印:65
线程2打印:66
线程1打印:67
线程2打印:68
线程1打印:69
线程2打印:70
线程1打印:71
线程2打印:72
线程1打印:73
线程2打印:74
线程1打印:75
线程2打印:76
线程1打印:77
线程2打印:78
线程1打印:79
线程2打印:80
线程1打印:81
线程2打印:82
线程1打印:83
线程2打印:84
线程1打印:85
线程2打印:86
线程1打印:87
线程2打印:88
线程1打印:89
线程2打印:90
线程1打印:91
线程2打印:92
线程1打印:93
线程2打印:94
线程1打印:95
线程2打印:96
线程1打印:97
线程2打印:98
线程1打印:99
线程2打印:100

Process finished with exit code 0

参考

https://xindoo.blog.csdn.net/article/details/80004003

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Java并发】生产者消费者模型 - 两线程交替打印1-100 的相关文章

  • SPNEGO 密码身份验证问题

    我已将我的应用程序配置为通过 SPNEGO 与 Websphere 使用 Kerberos 身份验证 这是详细信息 krb5 conf libdefaults default realm ABC MYCOMPANY COM default
  • 将构造函数作为参数传递给方法

    我是java新手 开始研究构造函数 我看到一些构造函数作为参数传递给方法的示例 请告诉我当构造函数作为参数传递给方法时会发生什么 或者建议我一些链接 我可以在其中获得有关使用构造函数的足够知识 根据您需要传递构造函数的目的 您可以考虑传递供
  • 在 Java 中使用 Batik 检查和删除 SVG 中的属性

    这个问题基本上说明了一切 如何检查 SVG 是否具有 viewBox 属性 我正在使用蜡染库 我需要这个 因为我需要 至少 通知用户有一个 viewBox 属性 我可以删除它吗 使用 org w3c dom 类 您可以按照以下方式做一些事情
  • 在 jTextfield 中禁用“粘贴”

    我有一个用 Swing awt 编写的应用程序 我想阻止用户将值粘贴到文本字段中 有没有办法在不使用动作监听器的情况下做到这一点 您可以使用 null 参数调用 setTransferHandler 如下所示 textComponent s
  • 如何作为应用程序发布到页面?

    所以 我有一个应用程序 Facebook 应用程序实体 并且我有一个页面 我想使用应用程序通过java代码 通过restfb或任何其他建议 发布到页面 看起来我错过了页面授予应用程序发布权限的阶段 不知道该怎么做 谢谢你们 乌里 您只能 作
  • 重写 getPreferredSize() 会破坏 LSP

    我总是在这个压倒一切的网站上看到建议getPreferredSize 而不是使用setPreferredSize 例如 如前面的线程所示 对于固定大小的组件 使用重写 getPreferredSize 而不是使用 setPreferredS
  • 如何在 HandlerInterceptorAdapter 中添加 HttpServletRequest 标头?

    我正在尝试将授权标头添加到我的请求中 作为我们切换环境时的临时解决方法 我试图在扩展 HandlerInterceptorAdapter 的拦截器中处理它 我使用 MutableHttpServletRequest 类制作here http
  • 纱线上的火花,连接到资源管理器 /0.0.0.0:8032

    我正在我的开发机器 Mac 上编写 Spark 程序 hadoop的版本是2 6 spark的版本是1 6 2 hadoop集群有3个节点 当然都在linux机器上 我在idea IDE中以spark独立模式运行spark程序 它运行成功
  • 在带有 Protocol Buffers 的项目中使用 Proguard 有什么特点?

    我有一个使用 Google Protocol Buffers 的项目 一旦我尝试用 ProGuard 对其进行混淆 似乎 protobuf 会导致问题 我将所有自己的类打包成mybuildedclasses jar 谷歌代码被打包成prot
  • 为什么无法从 WEB-INF 文件夹内加载 POSModel 文件?

    我在我的 Web 项目中使用 Spring MVC 我将模型文件放在 WEB INF 目录中 String taggerModelPath WEB INF lib en pos maxent bin String chunkerModelP
  • 如何在不反编译的情况下更改已编译的.class文件?

    我想更改 class 文件方法 我安装 JD Eclipse Decompiler 并打开 class 文件 我添加了一些代码并保存 class 文件 但是 class 文件没有改变 我不知道如何使用反编译器 如果可能的话 如何在不使用反编
  • Java 中 JButton 的击键/热键

    最初我使用 JMenu 并建立热键以使用加速器工作 它运行得很好 现在我想在 JButton 中实现相同的行为 但我陷入困境 这是我编写的代码 请分享您的想法 以便我可以走上正确的道路 import javax swing import j
  • C 与 C++ 中的 JNI 调用不同?

    所以我有以下使用 Java 本机接口的 C 代码 但是我想将其转换为 C 但不知道如何转换 include
  • BadPaddingException:无效的密文

    我需要一些帮助 因为这是我第一次编写加密代码 加密代码似乎工作正常 但解密会引发错误 我得到的错误是 de flexiprovider api exceptions BadPaddingException 无效的密文 in the 解密函数
  • 当底层连接是有状态时如何使用 Apache HttpClient?

    我在谷歌上搜索了很多关于如何使用 HttpClient 进行多线程处理的信息 他们中的大多数人建议使用 ThreadSafeClientConnManager 但我的应用程序必须登录某个主机 登录表单页面 以便 HttpClient 获得底
  • 使用 PC/SC 读卡器验证 Ultralight EV1

    我在尝试使用 Java 中的 PC SC 读卡器 特别是 ACR1222L 验证 Ultralight EV1 卡时遇到问题 我能够使用 ISO 14443 3 标签的相应 APDU 在不受保护的标签上进行写入和读取 但是 我找不到运行 P
  • 如何从 JavaFX 中的另一个控制器类访问 UI 元素?

    我有一个使用 NetBeans 8 编写的 JavaFX Java 8 应用程序 没有SceneBuilder 我的应用程序有一个主窗口 该窗口有自己的 FXML 文件 primary fxml 和自己的控制器类 FXMLPrimaryCo
  • java.lang.IllegalStateException - 提交响应后无法创建会话

    我在我的项目中使用 JSF PrimeFaces 我为此准备了一个Maven项目 当我编译项目并加载主页后 我收到以下异常 java lang IllegalStateException Cannot create a session af
  • 在实现使用原始类型的接口时如何避免警告?

    我正在实施流程工厂 http help eclipse org ganymede index jsp topic org eclipse platform doc isv reference api org eclipse debug co
  • 如何建立与 FileZilla Server 1.2.0 的 FTPS 数据连接

    使用 Apache commons net 的 Java FTPSClient 进行会话恢复是一个已知问题 会话恢复是 FTPS 服务器数据连接所需的一项安全功能 Apache FTPSClient 不支持会话恢复 并且 JDK API 使

随机推荐

  • 【docker】docker-compose安装带ui页面的kafka集群

    docker compose 安装带kafka ui 的kafka集群 在日常的工作当中 kafka集群作为常用的中间件 其搭建过程略显繁琐 需要配置的文件颇多 为了方便各位初学者快速体验kafka的魅力 本文采取一键式安装kafka 3
  • 华为机试(字符串消消乐---Java实现)

    package test import java util Scanner 消消乐 字符串 描述 给定一个只包含大小写字母的字符串 大小写敏感 若相邻两个元素相等则消除 直到最后字符串消除不了了 输出消消乐后字符串的长度 若遇到非大小写字母
  • layui实现左侧菜单点击右侧内容区显示

    layui这个前端框架对后端人员来说提供了极大的方便 很大一部分同学在刚接触到这个框架就迫不及待的要动手实践了 刚好最近需要开发一个后台管理项目 就拿layui来进行学习和实践 还没有接触到的同学可以先通读一遍文档 这样在遇到问题的时候才能
  • 用C语言打造 时间戳转换成北京时间格式

    本函数适用于SMT32F10x GD32F10x的RTC时间戳转换成有效年月日和时间 uint8 t const Year a 12 31 28 31 30 31 30 31 31 30 31 30 31 uint8 t const Yea
  • 银联支付开发、使用的一些总结

    现在的网页支付 PC和微信H5 和app支付 用的比较多的是微信支付 银联支付和支付宝支付 其余的是这些支付的第三方支付 我目前了解的只有这么多 我目前做了银联支付和微信支付 这里说一些银联支付的开发的一些介绍吧 根据我们公司的应用经验 银
  • uevent 事件上报demo

    1 驱动上报 diff git a kernel msm 3 18 drivers input touchscreen ft8006u focaltech core c b kernel msm 3 18 drivers input tou
  • HTML5根据浏览器获取经度和纬度(百度API)

    网页获取用户位置信息的办法1 调用百度地图的地图标注功能 通过百度地图API获取对应的经度和纬度进而获取地区信息 优点是比较准确 缺点是需要用户自己选择位置2 通过H5 geolocation属性获取经度和纬度 优点是用户只需要点击允许获取
  • 设计模式的七大原则

    七大原则 开闭原则 Open Close Principle OCP 一个软件实体如类 模块和函数应该对扩展开放 对修改关闭 目的就是保证程序的扩展性好 易于维护和升级 开闭原则被称为面向对象设计的基石 实际上 其他原则都可以看作是实现开闭
  • ICML 2012 推荐系统部分文章小结及下载

    ICML2012 paper下载地址 感谢丹柯提供 http icml cc 2012 papers 个人比较感兴趣的 跟推荐系统相关的几篇文章 1 在有query的场景下 向用户推荐item Latent Collaborative Re
  • 解决视频在钉钉播放出现转码或闪烁

    问题 用录屏软件 如傲软录屏 录制的视频通过钉钉发送给对方后 接收方直接点开视频播放时会提示转码或出现画面闪烁 原因 钉钉要求的视频的像素格式为yuv420p 而录屏软件的像素格式不符 例如 傲软录屏使用h264编码时视频的像素格式是yuv
  • 什么是spark机器学习

    Spark机器学习 Spark ML 是Apache Spark的一个模块 用于进行大规模数据处理和机器学习任务 它提供了一组丰富的工具和算法 用于构建和训练机器学习模型 以及进行数据预处理和特征工程 Spark ML的设计目标是高效处理大
  • Java把V3音频文件转化为wav文件的算法的代码

    将写内容过程经常用到的内容段做个备份 如下内容内容是关于Java把V3音频文件转化为wav文件的算法的内容 import java io BufferedInputStream import java io BufferedOutputSt
  • C语言解决猴子分桃问题的代码

    研发闲暇时间 把做工程过程中经常用的代码片段做个记录 如下的资料是关于C语言解决猴子分桃问题的代码 希望能对大家有较大帮助 main int i m j k count for i 4 i lt 10000 i 4 count 0 m i
  • Q_UNUSED ( name ) 的用法

    一 用法 Q UNUSED 没有实质性的作用 用来避免编译器警告 for example int transition getSTL int type Q UNUSED type return 123 二 相关问题处理 如果编译中出现以下警
  • MySQL之窗口函数

    目录 1 窗口函数基本概念 2 窗口函数和普通聚合函数的区别 3 常见的窗口函数 4 窗口函数的使用 5 示例代码 聚合函数也可以作为窗口函数 聚合函数VS窗口函数 常见窗口函数的使用 编辑给窗口指定别名 怎么样得到各部门工资排名前N名员工
  • C++的noexcept

    在C 中 noexcept是一个异常说明符 用于告知编译器一个函数是否会抛出异常 使用noexcept可以提供编译器有关函数异常处理的信息 从而优化代码 noexcept有两种形式 noexcept和noexcept expression
  • 10种流行的Java框架

    任何框架都是有助于更快更好地开发软件解决方案的工具之一 框架的基本原理不必重新发明轮子 框架使开发人员的工作变得更轻松 并帮助他们专注于业务逻辑 而不必担心通用的代码段 而且由于Java并不是最简单的编程语言之一 因此框架在这里绝对是有用的
  • Apache Doris 快速入门

    1 基本概念 FE Frontend 前端节点 接收用户查询请求 SQL解析 执行计划生成 元数据管理 节点管理等 BE Backend 后端节点 数据存储 执行查询计划 前端节点FE 和 后端节点BE 各自独立运行 互不影响 broker
  • Huggingface Transformers简约教程(二)

    写在前面 致敬所有前辈 知乎上的transformers 教程 博客园上的Colab 使用教程 huggingface 官网 6 设计思想 The library was designed with two strong goals in
  • 【Java并发】生产者消费者模型 - 两线程交替打印1-100

    生产者消费者模型 以下是其中一种通过synchronize的实现 import java util Queue import java util LinkedList public class ProducerAndConsumer pri