Java 多线程循环打印

文章目录

  • 一、标志变量 + 互斥锁
  • 二、标志变量 + synchronized
  • 三、标志变量 + 互斥锁 + 条件变量
  • 四、原子变量
  • 五、信号量


一、标志变量 + 互斥锁

标志变量用于标识当前应该是哪个线程进行输出,互斥锁用于保证对标志变量的互斥访问。

public class Main {private static int currentThread = 0;  // 标志变量private static final Lock lock = new ReentrantLock();  // 互斥锁public static void main(String[] args) {Thread threadA = new Thread(() -> print("A", 0));Thread threadB = new Thread(() -> print("B", 1));Thread threadC = new Thread(() -> print("C", 2));threadA.start();threadB.start();threadC.start();}private static void print(String message, int threadId) {try {for (int i = 0; i < 10; i++) {lock.lock();while (threadId != currentThread) {lock.unlock();Thread.sleep(1);  // 让权等待,非必需lock.lock();}System.out.print(message);currentThread = (currentThread + 1) % 3;lock.unlock();}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

二、标志变量 + synchronized

通过在非静态方法以当前类作为锁可以避免显式的锁定义。

public class Main {public static void main(String[] args) {Print print = new Print();Thread threadA = new Thread(() -> print.loopPrint("A", 0));Thread threadB = new Thread(() -> print.loopPrint("B", 1));Thread threadC = new Thread(() -> print.loopPrint("C", 2));threadA.start();threadB.start();threadC.start();}
}
public class Print {private int currentThread = 0;  // 标志变量public void loopPrint(String message, int threadId) {try {for (int i = 0; i < 10; i++) {synchronized (this) {while (threadId != currentThread) {this.wait();}System.out.print(message);currentThread = (currentThread + 1) % 3;this.notifyAll();}}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

三、标志变量 + 互斥锁 + 条件变量

public class Main {private static int currentThread = 0;  // 标志变量private static final Lock lock = new ReentrantLock();  // 互斥锁private static final Condition condition = lock.newCondition();  // 条件变量public static void main(String[] args) {Thread threadA = new Thread(() -> print("A", 0));Thread threadB = new Thread(() -> print("B", 1));Thread threadC = new Thread(() -> print("C", 2));threadA.start();threadB.start();threadC.start();}private static void print(String message, int threadId) {try {for (int i = 0; i < 10; i++) {lock.lock();while (threadId != currentThread) {condition.await();}System.out.print(message);currentThread = (currentThread + 1) % 3;condition.signalAll();lock.unlock();}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

四、原子变量

AtomicInteger 通过 CAS、volatilenative 方法保证了原子操作,同时避免了 synchronized 的高开销。

public class Main {private static final AtomicInteger currentThread = new AtomicInteger(0);  // 原子变量public static void main(String[] args) {Thread threadA = new Thread(() -> print("A", 0));Thread threadB = new Thread(() -> print("B", 1));Thread threadC = new Thread(() -> print("C", 2));threadA.start();threadB.start();threadC.start();}private static void print(String message, int threadId) {for (int i = 0; i < 10; i++) {while (threadId != currentThread.get()) {Thread.yield();  // 让权等待}System.out.print(message);currentThread.set((currentThread.get() + 1) % 3);}}
}

五、信号量

public class Main {private static final Semaphore semaphoreA = new Semaphore(1);private static final Semaphore semaphoreB = new Semaphore(0);private static final Semaphore semaphoreC = new Semaphore(0);public static void main(String[] args) {Thread threadA = new Thread(() -> print("A", semaphoreA, semaphoreB));Thread threadB = new Thread(() -> print("B", semaphoreB, semaphoreC));Thread threadC = new Thread(() -> print("C", semaphoreC, semaphoreA));threadA.start();threadB.start();threadC.start();}private static void print(String message, Semaphore currentSemaphore, Semaphore nextSemaphore) {for (int i = 0; i < 10; i++) {try {currentSemaphore.acquire();System.out.print(message);nextSemaphore.release();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}

在这里插入图片描述

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

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

相关文章

推荐几款免费的智能AI伪原创工具

在当今信息快速传播的时代&#xff0c;创作者们常常为了在激烈的竞争中脱颖而出而苦苦挣扎&#xff0c;而其中的一项挑战就是创作出独具创意和独特性的内容。然而&#xff0c;时间有限的现实让很多人望而却步。在这个背景下&#xff0c;免费在线伪原创工具成为了创作者们的得力…

抑制过拟合——Dropout原理

抑制过拟合——Dropout原理 Dropout的工作原理 实验观察 在机器学习领域&#xff0c;尤其是当我们处理复杂的模型和有限的训练样本时&#xff0c;一个常见的问题是过拟合。简而言之&#xff0c;过拟合发生在模型对训练数据学得太好&#xff0c;以至于它捕捉到了数据中的噪声和…

MacOS + Android Studio 通过 USB 数据线真机调试

环境&#xff1a;Apple M1 MacOS Sonoma 14.1.1 软件&#xff1a;Android Studio Giraffe | 2022.3.1 Patch 3 设备&#xff1a;小米10 Android 13 一、创建测试项目 安卓 HelloWorld 项目: 安卓 HelloWorld 项目 二、数据线连接手机 1. 手机开启开发者模式 参考&#xff1…

Jmeter+ant+jenkins实现持续集成看这一篇就搞定了!

jmeterantjenkins持续集成 一、下载并配置jmeter 首先下载jmeter工具&#xff0c;并配置好环境变量&#xff1b;参考&#xff1a;https://www.cnblogs.com/YouJeffrey/p/16029894.html jmeter默认保存的是.jtl格式的文件&#xff0c;要设置一下bin/jmeter.properties,文件内容…

【前端】多线程 worker

VUE3 引用 npm install worker-loader 在vue.config.js文件的defineConfig里加上配置参数 chainWebpack: config > {config.module.rule(worker-loader).test(/\.worker\.js$/).use({loader: worker-loader,options: {inline: true}}).loader(worker-loader).end()}先在…

传教士与野人过河问题

代码模块参考文章&#xff1a;传教士与野人过河问题&#xff08;numpy、pandas&#xff09;_python过河问题_醉蕤的博客-CSDN博客 问题描述 一般的传教士和野人问题&#xff08;Missionaries and Cannibals&#xff09;&#xff1a;有N个传教士和C个野人来到河边准 备渡河。…

EasyMicrobiome-易扩增子、易宏基因组等分析流程依赖常用软件、脚本文件和数据库注释文件

啥也不说了&#xff0c;这个好用&#xff0c;给大家推荐&#xff1a;YongxinLiu/EasyMicrobiome (github.com) 大家先看看引用文献吧&#xff0c;很有用&#xff1a;https://doi.org/10.1002/imt2.83 还有这个&#xff0c;后面马上介绍&#xff1a;YongxinLiu/EasyAmplicon: E…

mabatis基于xml方式和注解方式实现多表查询

前面步骤 http://t.csdnimg.cn/IPXMY 1、解释 在数据库中&#xff0c;单表的操作是最简单的&#xff0c;但是在实际业务中最少也有十几张表&#xff0c;并且表与表之间常常相互间联系&#xff1b; 一对一、一对多、多对多是表与表之间的常见的关系。 一对一&#xff1a;一张…

zookeeper 单机伪集群搭建简单记录(实操课程系列)

本系列是zookeeper相关的实操课程&#xff0c;课程测试环环相扣&#xff0c;请按照顺序阅读测试来学习zookeeper 1、官方下载加压后&#xff0c;根目录下新建data和log目录&#xff0c;然后分别拷贝两份&#xff0c;分别放到D盘&#xff0c;E盘&#xff0c;F盘 2、data目录下面…

基于SSM的影视创作论坛设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

docker集群的详解以及超详细搭建

文章目录 一、问题引入1. 多容器位于同一主机2. 多容器位于不同主机 二、介绍三、特性四、概念1. 节点nodes2. 服务(service)和任务(task)3. 负载均衡 五、docker网络1. overlay网络 六、docker集群搭建1. 环境介绍2. 创建集群3. 集群网络4. 加入工作节点 七、部署可视化界面po…

[NOIP2016 普及组] 回文日期

枚举好题&#xff0c;直接枚举答案 看看在不在范围内就行了 注意二月份 92200229是合法的~ 82200228也是合法的&#xff01; #include<bits/stdc.h> using namespace std;map<int,int>mp;int main() {mp[1] mp[3] mp[5] mp[7] mp[8] mp[10] mp[12] 31;mp[…