Java 多线程循环打印

news2024/9/24 21:26:48

文章目录

  • 一、标志变量 + 互斥锁
  • 二、标志变量 + 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.coloradmin.cn/o/1272151.html

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

相关文章

分享常见msvcp140.dll丢失的解决方法,msvcp140.dll修复的问题

在使用电脑的过程中可能会出现关于msvcp140.dll丢失的问题&#xff0c;通常出现这样的问题都会导致电脑中的程序出现不能正常运行的情况。并且如果不及时将msvcp140.dll修复的话可能还会导致电脑出现其他的问题。这篇文章就将给大家介绍关于msvcp140.dll丢失的解决方法。 一.常…

美国第三季度经济GDP数据亮眼,其增长率上修至近2年最快

KlipC报道&#xff1a;美国商务部公布美国第三季度GDP按年率增长5.2%&#xff0c;较首次预估数据上调了0.3%。也是近2年来最快增速。 KlipC的分析师表示&#xff1a;“相较于第二季度相比&#xff0c;第三季度的时机GDP主要反映了消费者指出和私人库存投资的加速和出口的上升。…

Prosys OPC Client连接OPC DA

Prosys OPC Client连接OPC DA Prosys OPC 客户端将帮助排除 OPC 连接故障并测试 OPC 服务器。 您可以读写数据、浏览服务器以及导出和导入地址空间。 OPC 客户端轻巧、快速且易于使用。 支持 OPC DA 1.0a 和 OPC DA 2.05a 官方地址: https://www.prosysopc.com/products/opc-…

XUbuntu22.04之安装OBS30.0强大录屏工具(一百九十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

颜色十六进制代码对照表

白色 #FFFFFF 2 红色 #FF0000 3 绿色 #00FF00 蓝色 #0000FF 5 牡丹红 #FF00FF 6 青色 #00FFFF 黄色 #FFFF00 8 黑色 #000000 9 海蓝 #70DB93 巧克力色 #5C3317 11 蓝紫色 #9F5F9F 12 黄铜色 #B5A642 亮金色 #D9D919 14 棕色 #A67D3D 15 青铜色 #8C7853 2号青铜色 #A67D3D 17 士…

基于SSM搭建系统

原理 SSM集成 SpringSpringMvcMybatis集成 框架集成核心&#xff0c;如果你的项目中&#xff0c;用到了Spring框架&#xff0c;那么其他框架主要就是和Spring集成&#xff1b; 和Spring集成的核心思路&#xff1a; 把当前框架的核心类&#xff0c;交给Spring管理&#xff08…

C++: string的模拟实现

C: string的模拟实现 一.前置说明1.模拟实现string容器的目的2.我们要实现的大致框架 二.默认成员函数1.构造函数2.拷贝构造函数1.传统写法2.现代写法 3.析构函数4.赋值运算符重载1.传统写法2.现代写法 三.遍历和访问1.operator[]运算符重载2.iterator迭代器 四.容量相关函数1.…

ant design vue3 处理 ant-card-head ant-tabs靠左边对齐之has选择器不生效

火狐浏览器是不支持has的。 解决方法&#xff1a;通过position来解决。

拥抱未来:大语言模型解锁平台工程的无限可能

01 了解大型语言模型 (LLM) 大型语言模型&#xff08;LLM&#xff09;是一种人工智能&#xff08;AI&#xff09;算法&#xff0c;它使用深度学习技术和海量数据集来理解、总结、生成和预测新内容。凭借合成大量信息的能力&#xff0c;LLM 可以提高以前需要人类专家的业务流程的…

2002-2021年全国各省产业结构合理化高级化指数数据(含原始数据+计算过程+计算结果)

2002-2021年全国各省产业结构合理化高级化指数数据&#xff08;含原始数据计算过程计算结果&#xff09; 1、时间&#xff1a;2002-2021年 2、指标&#xff1a;地区、时间、就业总人数&#xff08;万人&#xff09;、第一产业就业人数&#xff08;万人&#xff09;、第二产业…

C语言从入门到实战——常用字符函数和字符串函数的了解和模拟实现

常用字符函数和字符串函数的了解和模拟实现 前言1. 字符分类函数2. 字符转换函数3. strlen的使用和模拟实现4. strcpy的使用和模拟实现5. strcat的使用和模拟实现6. strcmp的使用和模拟实现7. strncpy函数的使用8. strncat函数的使用9. strncmp函数的使用10. strstr的使用和模拟…

中通快递查询,中通快递单号查询,分析筛选出多次揽收件

批量查询中通快递单号的物流信息&#xff0c;并将其中的多次揽收件分析筛选出来。 所需工具&#xff1a; 一个【快递批量查询高手】软件 中通快递单号若干 操作步骤&#xff1a; 步骤1&#xff1a;运行【快递批量查询高手】软件&#xff0c;第一次使用的朋友记得先注册&…

阿里云ACP认证考试快速通关攻略,请收好!

目前云计算人才紧缺&#xff0c;预计2025年我国云计算产业人才缺口预计将达到150万&#xff0c;因此现在云计算工程师的薪资是相当可观的。而阿里云从2016年起就一直在国内市场占据着领先地位 。 阿里云目前稳居国内云计算市场第一&#xff0c;比排后面5名同行市场占有率的总和…

换抵挡装置(按位运算符的运用)

给出两个长度分别为n1&#xff0c;n2&#xff08;n1 n2 <32)且每列高度只为1或2的长条&#xff08;保证高度为1的地方水平上一致&#xff09;。需要将它们放入一个高度为3的容器长度&#xff0c;问能够容纳它们的最短容器长度 用手画的 本来是n1&#xff0c;n2 < 100的…

串口更新app程序(参考他人资料)

一&#xff1a;参考资料 1.选定镁光的falsh Debug一下bootloader工程&#xff0c;串口只输出了一个SREC SPI Bootloader。单步调试发现&#xff0c;是XIsf_Initialize出错了&#xff0c;返回了1&#xff0c;程序直接退出了main函数。再继续分析&#xff0c;发现程序走的是Atm…

2023.11.29 -hmzx电商平台建设项目 -核销主题阶段总结

目录 1.准备源数据 2.准备数仓工具进行源数据同步到ods层,本项目使用Datax 3.使用Datax完成数据同步前建表时的方案选择 3.1同步方式区别: 3.2存储格式和压缩区别: 4.在hive中创建表,共31个表 5.数仓概念 和 数仓建模方案 5.1数仓的基本概念 5.2 数仓建模方案 关系建模…

java论坛数据以及搜索接口实现

一. 内容简介 java论坛数据以及搜索接口实现 二. 软件环境 2.1 java 1.8 2.2 mysql Ver 8.0.13 for Win64 on x86_64 (MySQL Community Server - GPL) 2.3 IDEA ULTIMATE 2019.3 2.4d代码地址 三.主要流程 3.1 创建数据库,创建数据表 3.2 开始编写接口&#xff0c;并测…

C/C++不定参数的使用

文章目录 C语言的不定参C的不定参 C语言的不定参 C语言的不定参数最常见的应用示例就是printf函数&#xff0c;如下&#xff0c;参数列表中的...表示不定参数列表 #include <stdio.h> int printf(const char *format, ...);试着模拟实现C语言的printf函数 void myprin…

新手村之SQL——分组与子查询

1.GROUP BY GROUP BY 函数就是 SQL 中用来实现分组的函数&#xff0c;其用于结合聚合函数&#xff0c;能根据给定数据列的每个成员对查询结果进行分组统计&#xff0c;最终得到一个分组汇总表。 mysql> SELECT country, COUNT(country) AS teacher_count-> FROM teacher…

Linux系统部署Tale个人博客并发布到公网访问

文章目录 前言1. Tale网站搭建1.1 检查本地环境1.2 部署Tale个人博客系统1.3 启动Tale服务1.4 访问博客地址 2. Linux安装Cpolar内网穿透3. 创建Tale博客公网地址4. 使用公网地址访问Tale 前言 今天给大家带来一款基于 Java 语言的轻量级博客开源项目——Tale&#xff0c;Tale…