首页 > 其他分享 >多线程轮流打印字符

多线程轮流打印字符

时间:2024-09-08 18:26:14浏览次数:7  
标签:字符 cnt cur int lock 打印 static new 多线程

要求:使用多个线程轮流打印字符

  1. 方法1。无锁自旋,一般在多核机器并且临界区耗时很短的话可以尝试自旋
public class printABC {
    static Logger log = new Logger(Logger.LogLevel.DEBUG, printABC.class);
    static volatile int cur = 0;
    public static void main(String[] args) {
        String[] strings = {"A", "B", "C"};
        int n = strings.length;
        int printCnt = 100;
        int cnt = n * printCnt;
        for (int i = 0; i < n; i++) {
            int j = i;
            new Thread(() -> {
                while (cur < cnt) {
                    if (cur % n == j && cur < cnt) {
                        log.info(cur / n + " - " + strings[j]);
                        cur++;
                    }
                }
            }).start();
        }
    }
}
  1. 方法2。使用 ReentrantLock
public class printABC {
    static Logger log = new Logger(Logger.LogLevel.DEBUG, printABC.class);
    static volatile int cur = 0;
    static final ReentrantLock lock = new ReentrantLock();
    static Condition condition = lock.newCondition();

    public static void main(String[] args) {
        String[] strings = {"A", "B", "C"};
        int n = strings.length;
        int printCnt = 100;
        int cnt = n * printCnt;
        for (int i = 0; i < n; i++) {
            int j = i;
            new Thread(() -> {
                while (cur < cnt) {
                    lock.lock();
                    try {
                        if (cur % n == j && cur < cnt) {
                            log.info(cur / n + " - " + strings[j]);
                            cur++;
                            condition.signalAll();
                        }else{
                            condition.await();
                        }
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    } finally {
                        lock.unlock();
                    }
                }
            }).start();
        }
    }
}
  1. 方法3。使用 synchronized
public class printABC {
    static Logger log = new Logger(Logger.LogLevel.DEBUG, printABC.class);
    static volatile int cur = 0;
    static final ReentrantLock lock = new ReentrantLock();
    public static void main(String[] args) {
        String[] strings = {"A", "B", "C"};
        int n = strings.length;
        int printCnt = 100;
        int cnt = n * printCnt;
        for (int i = 0; i < n; i++) {
            int j = i;
            new Thread(() -> {
                while (cur < cnt) {
                    synchronized (lock) {
                        if (cur % n == j && cur < cnt) {
                            log.info(cur / n + " - " + strings[j]);
                            cur++;
                            lock.notifyAll();
                        } else {
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                }
            }).start();
        }
    }
}

对于初学者来说需要注意的点:

  1. 如果使用加锁方式的话,在线程调用阻塞方法时需要先获取到锁,否则会抛异常
  2. 当线程被唤醒时需要注意虚假唤醒的情况
  3. 多线程共享变量 volatile 是一定要加的

标签:字符,cnt,cur,int,lock,打印,static,new,多线程
From: https://www.cnblogs.com/ZGByoyo/p/18403207

相关文章

  • C++字符串中的string类操作
    愿我如星君如月,夜夜流光相皎洁。                           ——《车逍遥篇》【宋】范成大目录正文:主要特点:基本操作: 代码演示:总结:今天我们接着上次的章节继续,这次我们来说一个为解决上个方法的缺陷而诞生......
  • 图论篇--代码随想录算法训练营第五十三天打卡| 110. 字符串接龙,105.有向图的完全可达
    110.字符串接龙题目链接:110.字符串接龙题目描述:字典strList中从字符串beginStr和endStr的转换序列是一个按下述规格形成的序列: 序列中第一个字符串是beginStr。序列中最后一个字符串是endStr。 每次转换只能改变一个字符。 转换过程中的中间字符串必须是字典......
  • 如何防止公司打印泄密?防止打印机泄密的六大方法,包教包会!
    打印机,一个信息输出的重要设备,其安全性却往往被忽视。无论是内部员工的有意泄露,还是设备本身的安全漏洞,都可能让敏感信息如公司机密、客户资料等轻易落入他人之手。那么,我们应该采取哪些措施来防止打印机泄密呢?本文参考域智盾软件,为大家分享6大方法!一、设置访问权限与密码保......
  • C语言练习题--一维、二维字符串数组
    1.下列对C语言字符数组的描述中错误的是(D) A.字符数组可以存放字符串B.字符数组中的字符串可以整体输入、输出C.不可以用关系运算符对字符数组中的字符串进行比较D.可以在赋值语句中通过赋值运算符"="对字符数组整体赋值分析:D只能逐个字符进行复制或者利用字......
  • Python中如何实现字符串的查询和替换?
    在Python中,字符串的查询和替换是字符串处理中的基础且常用的操作。Python提供了多种方法来实现这些功能,包括使用内置的方法、正则表达式等。一、字符串的查询字符串的查询通常指的是在字符串中查找子串的位置、出现的次数,或者检查子串是否存在等。Python的字符串对象提供了多......
  • 844. 比较含退格的字符串
    c++字符串还是不太熟练classSolution{public:boolbackspaceCompare(strings,stringt){returndealString(s)==dealString(t);}private:stringdealString(conststring&s){stringret;intcurIndex=0;while(......
  • 代码随想录算法训练营第九天 | Javascript | 力扣Leetcode | 手撕KMP的一天 | 28. 找
    目录前言简介题目链接:28.找出字符串中第一个匹配项的下标题目链接:459.重复的子字符串前言踏平坎坷成大道,斗罢艰险又出发!自律的尽头是自控,自控的尽头是硬控。愿道友们披荆斩棘,终能得偿所愿。简介本人是小几年经验的前端开发,算法基础只有力扣几十道题,非常薄弱。......
  • Python入门教程-Python 中的字符串及常用操作有哪些
    字符串是编程语言中最常见和最基础的数据类型之一。在Python中,字符串(string)是用于表示文本数据的序列。无论是处理用户输入、文件读写,还是处理网络数据,字符串都是编程中的关键工具之一。Python提供了许多方便的操作和方法来处理字符串数据。本文将带你从基础入门,详细介绍......
  • 如何打印CSDN博文和博客园博文
    如何打印CSDN博文和博客园博文相信大家看到一些比较不错的博文,都想打印保存一下,但是浏览器自带的打印会发生覆盖的问题并且除了博文之外的文字也会被打印,很不友好;这里提供一个新的方法:1、打开想要打印的博文;2、右键鼠标,选择检查,如图所示。3、点击检查,进入如下页面,选中Consol......
  • 深入掌握Go语言中的正则表达式与字符串处理
    Go语言中的正则表达式与模式匹配在编程中,字符串处理是常见的需求之一,而正则表达式则是一个强大的工具,能够帮助我们实现复杂的字符串匹配、提取和替换功能。Go语言内置了对正则表达式的支持,通过regexp包,我们可以轻松实现模式匹配的各种操作。本文将详细介绍正则表达式在Go语......