顺序打印数字的进一步理解

之前博客写了篇博文,面试时要求使用多线程顺序打印ABC循环20次,这是我当时使用join函数实现代码:

public class TestABCJoin {public static void main(String[] args) {// 创建任务Runnable taskA = () -> {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}};Runnable taskB = () -> {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}};Runnable taskC = () -> {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}};// 循环 20 次for (int i = 0; i < 20; i++) {Thread threadA = new Thread(taskA, "A");Thread threadB = new Thread(taskB, "B");Thread threadC = new Thread(taskC, "C");try {threadA.start(); // 启动 AthreadA.join();  // 等待 A 执行完毕threadB.start(); // 启动 BthreadB.join();  // 等待 B 执行完毕threadC.start(); // 启动 CthreadC.join();  // 等待 C 执行完毕} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}

这两天复习多线程,想到condition也可以实现这个需求,先贴上代码:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class TestABCLockCondition {public static void main(String[] args) {Alternate alternate = new Alternate();new Thread(() -> {for (int i = 0; i < 20; i++) {alternate.loopA(i);}}, "A").start();new Thread(() -> {for (int i = 0; i < 20; i++) {alternate.loopB(i);}}, "B").start();new Thread(() -> {for (int i = 0; i < 20; i++) {alternate.loopC(i);}}, "C").start();}
}class Alternate {private int number = 1; // 当前应执行的线程标记:1-A, 2-B, 3-Cprivate final Lock lock = new ReentrantLock();private final Condition conditionA = lock.newCondition();private final Condition conditionB = lock.newCondition();private final Condition conditionC = lock.newCondition();public void loopA(int totalLoop) {lock.lock();try {while (number != 1) {conditionA.await();}for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);}number = 2;conditionB.signal();} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}}public void loopB(int totalLoop) {lock.lock();try {while (number != 2) {conditionB.await();}for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);}number = 3;conditionC.signal();} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}}public void loopC(int totalLoop) {lock.lock();try {while (number != 3) {conditionC.await();}for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);}number = 1;conditionA.signal();} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}}
}

思考了下这两种方案的优缺点(deepseek总结):
使用 join() 实现顺序打印是一种简单直观的方式,适合小规模任务。但对于高并发场景,建议使用更高效的同步机制(如 ReentrantLock 和 Condition)。

好奇具体是为什么:
可以发现,第一种方法每次循环都需要创建新的线程(new Thread()),并在任务完成后销毁线程。我们知道线程的创建和销毁是非常昂贵的操作,尤其是在高并发场景下,频繁创建线程会导致性能急剧下降。
同时join() 会阻塞当前线程(通常是主线程),直到目标线程执行完毕。

使用信号量在高并发场景下的优势:
Condition 提供了 await() 和 signal() 方法,可以精确控制线程的等待和唤醒。
ReentrantLock 和 Condition 可以实现非阻塞的线程协作,避免主线程被阻塞。

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

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

相关文章

python学opencv|读取图像(五十四)使用cv2.blur()函数实现图像像素均值处理

【1】引言 前序学习进程中&#xff0c;对图像的操作均基于各个像素点上的BGR值不同而展开。 对于彩色图像&#xff0c;每个像素点上的BGR值为三个整数&#xff0c;因为是三通道图像&#xff1b;对于灰度图像&#xff0c;各个像素上的BGR值是一个整数&#xff0c;因为这是单通…

【开源免费】基于Vue和SpringBoot的工作流程管理系统(附论文)

本文项目编号 T 193 &#xff0c;文末自助获取源码 \color{red}{T193&#xff0c;文末自助获取源码} T193&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

IntelliJ IDEA远程开发代理远程服务器端口(免费内网穿透)

IntelliJ IDEA远程开发代理远程服务器端口&#xff08;免费内网穿透&#xff09;&#xff08;JetBrains家的其他IDE应该也支持&#xff09; 之前看到宇宙第一IDE VS Code好像默认代理了远程的端口&#xff0c;但是一直没找到IDEA的同类功能&#xff0c;这次终于发现了 以Intell…

文字显示省略号

多行文本溢出显示省略号

STM32_SD卡的SDIO通信_DMA读写

本篇&#xff0c;将使用CubeMXKeil&#xff0c;创建一个SD卡的DMA读写工程。 目录 一、简述 二、CubeMX 配置 SDIO DMA 三、Keil 编辑代码 四、实验效果 实现效果&#xff0c;如下图&#xff1a; 一、简述 上篇已简单介绍了SD、SDIO&#xff0c;本篇不再啰嗦&#xff0c;…

智能小区物业管理系统推动数字化转型与提升用户居住体验

内容概要 在当今快速发展的社会中&#xff0c;智能小区物业管理系统的出现正在改变传统的物业管理方式。这种系统不仅仅是一种工具&#xff0c;更是一种推动数字化转型的重要力量。它通过高效的技术手段&#xff0c;将物业管理与用户居住体验紧密结合&#xff0c;无疑为社区带…

基于STM32景区环境监测系统的设计与实现(论文+源码)

1系统方案设计 根据系统功能的设计要求&#xff0c;展开基于STM32景区环境监测系统设计。如图2.1所示为系统总体设计框图。系统以STM32单片机作为系统主控模块&#xff0c;通过DHT11传感器、MQ传感器、声音传感器实时监测景区环境中的温湿度、空气质量以及噪音数据。系统监测环…

八. Spring Boot2 整合连接 Redis(超详细剖析)

八. Spring Boot2 整合连接 Redis(超详细剖析) 文章目录 八. Spring Boot2 整合连接 Redis(超详细剖析)2. 注意事项和细节3. 最后&#xff1a; 在 springboot 中 , 整合 redis 可以通过 RedisTemplate 完成对 redis 的操作, 包括设置数据/获取数据 比如添加和读取数据 具体整…

【Unity3D】Tilemap俯视角像素游戏案例

目录 一、导入Tilemap 二、导入像素风素材 三、使用Tilemap制作地图 3.1 制作Tile Palette素材库 3.2 制作地图 四、实现A*寻路 五、待完善 一、导入Tilemap Unity 2019.4.0f1 已内置Tilemap 需导入2D Sprite、2D Tilemap Editor、以及一个我没法正常搜出的2D Tilemap…

企微SCRM驱动企业私域流量营销与客户关系管理的智慧革新

内容概要 在当今竞争激烈的商业环境中&#xff0c;企微SCRM逐渐成为企业实现私域流量营销和优化客户关系管理的重要工具。它的出现不仅提升了企业的工作效率&#xff0c;也改变了传统的营销方式。那么&#xff0c;究竟什么是企微SCRM呢&#xff1f;简单来说&#xff0c;它是将…

数据库、数据仓库、数据湖有什么不同

数据库、数据仓库和数据湖是三种不同的数据存储和管理技术&#xff0c;它们在用途、设计目标、数据处理方式以及适用场景上存在显著差异。以下将从多个角度详细说明它们之间的区别&#xff1a; 1. 数据结构与存储方式 数据库&#xff1a; 数据库主要用于存储结构化的数据&…

前端力扣刷题 | 6:hot100之 矩阵

73. 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 法一&#xff1a; var setZeroes function(matrix) {let setX new Set(); // 用于存储需要置零的行索引let setY new Set(); //…

【编译系列】Torch.compile()训练编译——算子融合逻辑 工程化

1. 背景: torch.compile()中,Dynamo作为前端负责计算图的捕获,后端有inductor、tvm等进行编译优化。 Dynamo:在Python字节码层面注入pass,实现bytecode-to-bytecode的优化,通过对bytecode逐行进行解析构建FX GraphInductor:负责对FX Graph进行AOTAutograd生成joint-gra…

Docker 部署教程jenkins

Docker 部署 jenkins 教程 Jenkins 官方网站 Jenkins 是一个开源的自动化服务器&#xff0c;主要用于持续集成&#xff08;CI&#xff09;和持续交付&#xff08;CD&#xff09;过程。它帮助开发人员自动化构建、测试和部署应用程序&#xff0c;显著提高软件开发的效率和质量…

2025/2/3 云服务器数据库与idea相连

幸福就摆在你面前&#xff0c;你却把阴影当成山川瀑布&#xff0c;你说你无法幸福。 轻量应用服务器https://swasnext.console.aliyun.com/servers/cn-heyuanhttps://swasnext.console.aliyun.com/servers/cn-heyuanhttps://swasnext.console.aliyun.com/servers/cn-heyuanhttp…

【memgpt】letta 课程1/2:从头实现一个自我编辑、记忆和多步骤推理的代理

llms-as-operating-systems-agent-memory llms-as-operating-systems-agent-memory内存 操作系统的内存管理

6. 【Vue实战--孢子记账--Web 版开发】-- 主币种设置

从这篇文章开始我们将一起实现孢子记账的功能&#xff0c;这篇文章实现主币种设置。这个功能比较简单&#xff0c;因此我们从这个功能开始做。 一、功能 根据项目前期的需求调研&#xff0c;用户需要在设置主币种的时候查看汇率信息&#xff08;别问为什么有这么个需求&#…

51单片机(STC89C52)开发:点亮一个小灯

软件安装&#xff1a; 安装开发板CH340驱动。 安装KEILC51开发软件&#xff1a;C51V901.exe。 下载软件&#xff1a;PZ-ISP.exe 创建项目&#xff1a; 新建main.c 将main.c加入至项目中&#xff1a; main.c:点亮一个小灯 #include "reg52.h"sbit LED1P2^0; //P2的…

GESP2023年9月认证C++六级( 第三部分编程题(2)小杨的握手问题)

参考程序1&#xff08;暴力枚举&#xff09; #include <iostream> using namespace std;int main() {int n 0;cin >> n; // 读入同学的数量int num[300000]; // 存储同学的学号for (int i 0; i < n; i) {cin >> num[i]; // 读入同学的进入顺序}long…

【C++篇】哈希表

目录 一&#xff0c;哈希概念 1.1&#xff0c;直接定址法 1.2&#xff0c;哈希冲突 1.3&#xff0c;负载因子 二&#xff0c;哈希函数 2.1&#xff0c;除法散列法 /除留余数法 2.2&#xff0c;乘法散列法 2.3&#xff0c;全域散列法 三&#xff0c;处理哈希冲突 3.1&…