[java] 控制三个线程按顺序交替输出数字123123…

控制三个线程按顺序交替输出数字123123…

synchronized(配合专用锁对象)

通过共享锁和 volatile 变量控制执行顺序,每个线程按指定顺序打印指定内容,确保输出序列如 “123123…”。使用 synchronizedwait/notifyAll 实现线程间协作。

/*** AlternateOutput类用于实现三个线程交替输出数字的功能* 通过使用synchronized关键字和wait/notify机制,确保三个线程按照1->2->3的顺序循环输出*/
public class AlternateOutput {/*** 用于线程同步的锁对象*/private static final Object lock = new Object();/*** 当前应该执行的线程编号*/private static int currentThreadNum = 1;/*** 每个线程需要执行的循环次数*/private static final int MAX_LOOP = 10;/*** 线程执行的任务方法,负责按照指定顺序输出内容* @param curThreadNum 当前线程的编号,用于判断是否轮到当前线程执行* @param nextThreadNum 下一个应该执行的线程编号,执行完当前任务后更新此值* @param output 当前线程需要输出的内容*/private static void runTask(int curThreadNum, int nextThreadNum, String output) {// 循环执行指定次数的任务for (int i = 0; i < AlternateOutput.MAX_LOOP; i++) {// 使用synchronized块确保线程安全synchronized (lock) {// 等待直到轮到当前线程执行while (AlternateOutput.currentThreadNum != curThreadNum) {try {lock.wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();return;}}// 输出当前线程的内容System.out.print(output);// 更新下一个应该执行的线程编号currentThreadNum = nextThreadNum;// 唤醒所有等待的线程lock.notifyAll();}}}/*** 程序入口点,创建并启动三个线程实现交替输出* @param args 命令行参数*/public static void main(String[] args) {// 创建第一个线程,负责输出"1"Thread t1 = new Thread(() -> {runTask(1, 2, "1");});t1.start();// 创建第二个线程,负责输出"2"Thread t2 = new Thread(() -> {runTask(2, 3, "2");});t2.start();// 创建第三个线程,负责输出"3"Thread t3 = new Thread(() -> {runTask(3, 1, "3");});t3.start();// 等待所有线程执行完成try {t1.join();t2.join();t3.join();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

ReentrantLock和Condition

通过ReentrantLockCondition控制执行顺序,确保按1→2→3循环打印10次。每个线程等待其编号轮次,执行打印后唤醒下一个线程。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class PrintNumber {public static final int MAX_LOOP = 10;public static int currentNum = 1;public static final ReentrantLock lock = new ReentrantLock();public static final Condition c1 = lock.newCondition();public static final Condition c2 = lock.newCondition();public static final Condition c3 = lock.newCondition();public static void main(String[] args) {Thread t1 = new Thread(new PrintNumberTask(1));Thread t2 = new Thread(new PrintNumberTask(2));Thread t3 = new Thread(new PrintNumberTask(3));t1.start();t2.start();t3.start();}
}
import java.util.concurrent.locks.Condition;public class PrintNumberTask implements Runnable {private int number;public PrintNumberTask(int num) {this.number = num;}private void printAndSwith(String output, int nextNum, Condition awaitCondition, Condition signalCondition)throws InterruptedException {while (PrintNumber.currentNum != this.number) {awaitCondition.await();}System.out.print(output);PrintNumber.currentNum = nextNum;signalCondition.signal();}@Overridepublic void run() {for (int i = 0; i < PrintNumber.MAX_LOOP; i++) {PrintNumber.lock.lock();try {switch (number) {case 1:printAndSwith("1", 2, PrintNumber.c1, PrintNumber.c2);break;case 2:printAndSwith("2", 3, PrintNumber.c2, PrintNumber.c3);break;case 3:printAndSwith("3", 1, PrintNumber.c3, PrintNumber.c1);break;default:break;}} catch (Exception e) {e.printStackTrace();} finally {PrintNumber.lock.unlock();}}}
}

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

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

相关文章

[C#]winform基于yolov8-seg实现的指甲分割实现源码

【测试环境】 vs2019 net framework4.7.2 onnxruntime1.16.3 opencvsharp 注意源码运行在CPU上不支持GPU运行&#xff0c;由于net framework限制GPU会很慢因此没有GPU版本提供。 【运行步骤】 打开sln项目 选择x64 debug运行即可 如需要再x64 release运行可以将x64 debu…

数据结构——线性表(链表,力扣中等篇,增删查改)

文章目录一、增删查改1.1增&#xff08;插入节点&#xff09;1.1.1两数后插入公约数1.1.2循环有序链表的插入1.2删&#xff08;移除节点&#xff09;1.2.1删除已知的node节点【交换val值】1.2.2移除数组中已存在的节点【unordered_set】1.2.3删除和为0的节点【前缀和】1.3改&am…

【Android】OkHttp发起GET请求 POST请求

三三要成为安卓糕手 一&#xff1a;OkHttp介绍 OkHttp 是一个开源的、强大且高效的 HTTP 客户端库&#xff0c;主要用于在 Java后端和Android 项目中进行网络请求。 //在gradle中添加依赖 com.squareup.okhttp3:okhttp:4.12.0二&#xff1a;GET请求/*** 使用OkHttp发起get请求*…

[Mysql数据库] 知识点总结8

1. 请详细描述在复制拓扑中参与复制的线程类型以及各自所承担的功能。答&#xff1a;当从属服务器连接到主服务器时&#xff0c;在主服务器上会创建 Binlog 转储线程&#xff0c;在从属服务器上会默 认创建 I/O 线程和 SQL 线程。- Binlog 转储线程用于从二进制日志读取事件并将…

250829-Gitlab数据备份与恢复

下面给你一份可落地的迁移方案&#xff0c;保证 GitLab 的数据和配置完整迁移到服务器 B。你当前用的是 GitLab Omnibus&#xff08;docker 版&#xff09;&#xff0c;数据都在你映射的 3 个目录里&#xff08;/etc/gitlab, /var/log/gitlab, /var/opt/gitlab&#xff09;&…

吴恩达机器学习作业十一:异常检测

数据集在作业一异常检测异常检测就是发现与大部分对象不同的对象&#xff0c;其实就是发现离群点。异常检测有时也称偏差检测。异常对象是相对罕见的。用数据集建立概率模型p ( x )&#xff0c;如果新的测试数据在这个模型上小于某个阈值&#xff0c;则说它极大可能为异常点算法…

2000w 的数据量,mysql要进行几次IO操作,为什么

在 MySQL 中&#xff0c;2000 万数据量的表在进行查询时所需的 ​​IO 操作次数​​主要取决于 ​​索引结构&#xff08;B树层级&#xff09;​​、​​查询类型​​和 ​​数据分布特征​​。以下是具体分析&#xff1a;一、B树层级与 IO 次数的关系InnoDB 引擎通过 B树索引管…

【代码随想录day 22】 力扣 39. 组合总和

视频讲解&#xff1a;https://www.bilibili.com/video/BV1KT4y1M7HJ/?vd_sourcea935eaede74a204ec74fd041b917810c 文档讲解&#xff1a;https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html#%E6%80%9D%E8%B7%AF 力扣题目&#xff1a;https://leetcod…

DrissionPage 实战:动态 IP 代理与百度翻译 API 数据抓取

本文将详细介绍如何使用 DrissionPage 实现动态 IP 代理访问&#xff0c;并结合百度翻译 API 进行数据抓取与处理。一、技术选型与架构设计1.1 为什么选择 DrissionPage&#xff1f;DrissionPage 作为新一代网络自动化工具&#xff0c;相比传统 Selenium Requests 方案具有显著…

策略模式:灵活应对算法动态切换

引言 在软件开发中&#xff0c;我们常常会遇到需要在运行时动态选择和切换算法或行为的场景。例如&#xff0c;电商系统中的多种支付方式、游戏中的不同难度设置&#xff0c;或是计算器中的各种运算符。传统的方法可能会使用复杂的条件判断语句&#xff08;如if-else或switch-c…

【C++ 】string类:深拷贝与浅拷贝解析

【C 】string类操作全解析-CSDN博客 1.stirng类的模拟实现 1.1 经典的string类问题 上面已经对string类进行了简单的介绍&#xff0c;大家只要能够正常使用即可。在面试中&#xff0c;面试官总喜欢要求自己来模拟实现string类&#xff0c;最主要是实现string类的构造、拷贝…

Decoder 解码器

Decoder 解码器&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h>#include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libswscale/swscale.h>#define WORD uint16_t #define DWORD ui…

globals() 小技巧

scheduler_class globals()[scheduler_class_name] Python 中一种 动态获取类对象 的常用技巧&#xff0c;属于 反射&#xff08;reflection&#xff09; 编程的范畴globals()Python 内置函数&#xff0c;返回一个 字典&#xff08;dict&#xff09;&#xff0c;包含当前模块&…

Android Studio 9.png制作

一、新建 二、把要做的图png导入进去 png图片建议 根据内容预留1像素可拉伸区域 eg:纯色或可渐变底色 三、右边创建.9.png 四、双击打开 1、绘制黑边 参考视频 2、缩放到800% ,移至右下 3、在下面和右边绘制整根黑线 4、根据png 位置左侧和上侧黑线 4.1 分析 红色方框为…

【百度】C++开发(25届提前批 一面)面经

文章目录1. 代码实现&#xff1a;说说LRU&#xff0c;并代码实现LRU为什么使用哈希表&#xff1f;&#xff08;有两个原因&#xff09;1. 仅用双向链表的缺陷2. 引入哈希表的作用1. 快速查找&#xff1a;2. 快速插入与删除&#xff1a;双向链表 哈希表的协作过程举例说明代码实…

Word文档怎么打印?Word打印技巧?【图文详解】单面/双面/指定页面/逆序等Word打印选项

一、问题背景 在日常办公、学习场景中&#xff0c;Word文档作为常用的文字处理载体&#xff0c;经常需要将电子内容转化为纸质版本&#xff0c;比如提交报告、打印学习资料、整理文档存档等。 但不少用户在尝试打印Word文档时&#xff0c;常会遇到各种阻碍&#xff1a;有的不清…

漫谈《数字图像处理》之基函数与基图像

在数字图像处理领域&#xff0c;基函数与基图像是贯穿理论分析与实际应用的核心概念 —— 它们如同 “乐高积木”&#xff0c;将复杂的图像信号拆解为可解释、可操作的基本单元&#xff0c;支撑起压缩、去噪、特征提取等一系列关键任务。从传统的傅里叶变换到前沿的因子场理论&…

打开多个Excel文件后快速关闭所有的文档,并且退出Excel应用

打开多个Excel文件后如果要快速关闭所有的文档&#xff0c;并且退出Excel应用&#xff0c;可以按住Shift键右上角的号&#xff08;关闭按钮&#xff09;。Word和PowerPoint也是一样的操作。如果有文档修改后没有保存&#xff0c;会提示是否保存。作为补充&#xff0c;先来看看两…

基于 PyTorch 构建 Dataset 与 DataLoader:从 TXT 文件读取到新增类别全流程指南

基于 PyTorch 构建 Dataset 与 DataLoader&#xff1a;从 TXT 文件读取到新增类别全流程指南在深度学习计算机视觉任务中&#xff0c;数据加载与预处理是模型训练的基础环节&#xff0c;直接影响模型的训练效率与最终性能。PyTorch 作为主流深度学习框架&#xff0c;提供了Data…

hive on tez如果是2个大表union会写几次临时文件到hdfs目录,数据量如何计算

如果是2个大表union会写几次临时文件到hdfs目录&#xff0c;数据量如何计算 在Hive on Tez中&#xff0c;两个大表执行UNION操作时&#xff0c;临时文件的写入次数和数据量&#xff0c;取决于UNION的类型&#xff08;UNION ALL还是UNION去重&#xff09;以及执行计划的Stage划分…