线程按顺序循环执行

这篇具有很好参考价值的文章主要介绍了线程按顺序循环执行。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

假设有3个线程,依次打印A、B、C,按顺序循环打印100次。
这个其实是线程通信,如果只是按顺序执行,用只有一个线程的线程池,依次提交线程任务就行,但是这里还不是每个线程只执行一次,需要循环重复打印。
这里有两种处理方式,一种是搞个全局int变量,对线程数取模,得到0~2,再转ASCII码。一种是3个线程按照创建时的顺序严格执行。

第一种思路写法:
这里只用到了原生的阻塞唤醒方法,线程竞争获取锁,确保同时只有一个线程累加countIndex和打印,3个线程的执行顺序就不是创建的顺序,而是随机的。

public class ThreeThreadPrintOrderlyBySync {

    private static final Object LOCK = new Object();
    private static volatile int countIndex = 0;
    private static final int MAX = 100;
    private static final int WORKER_COUNT = 3;

    public static void main(String[] args) {
        Thread thread1 = new Thread(new Worker(0));
        Thread thread2 = new Thread(new Worker(1));
        Thread thread3 = new Thread(new Worker(2));
        thread1.start();
        thread2.start();
        thread3.start();
    }

    public static class Worker implements Runnable {
        private final int index;

        public Worker(int index) {
            this.index = index;
        }

        @Override
        public void run() {
            while (countIndex < MAX) {
                synchronized (LOCK) {
                    try {
                        if (countIndex % WORKER_COUNT != index) {
                            LOCK.wait();
                        }
                        if (countIndex <= MAX) {
                            System.out.printf(String.valueOf((char) (65 + countIndex % WORKER_COUNT)));
                        }
                        countIndex++;
                        LOCK.notifyAll();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

}

第二种处理方式:
通过线程序号控制ReentrantLock中Condition的阻塞唤醒文章来源地址https://www.toymoban.com/news/detail-759701.html

public class ThreeThreadPrint {
    private static final int WORKER_COUNT = 3;
    private static final ReentrantLock LOCK = new ReentrantLock();
    private static int countIndex = 0;

    public static void main(String[] args) {
        List<Condition> conditions = new ArrayList<>();
        for (int i = 0; i < WORKER_COUNT; i++) {
            Condition condition = LOCK.newCondition();
            conditions.add(condition);
            Thread thread = new Worker(i, conditions);
            thread.start();
        }
    }

    public static class Worker extends Thread {
        private int index;
        private List<Condition> conditions;

        public Worker(int index, List<Condition> conditions) {
            super("Thread" + index);
            this.index = index;
            this.conditions = conditions;
        }

        @Override
        public void run() {
            while (true) {
                LOCK.lock();
                try {
                    if (countIndex % WORKER_COUNT != index) {
                        conditions.get(index).await();
                    }
                    if (countIndex > 100) {
                        conditions.get((index + 1) % conditions.size()).signal();
                        return;
                    }
                    System.out.printf(String.valueOf((char) (65 + countIndex % 3)));
                    countIndex++;
                    conditions.get((index + 1) % conditions.size()).signal();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                } finally {
                    LOCK.unlock();
                }
            }
        }
    }
}

到了这里,关于线程按顺序循环执行的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java中代码的执行顺序

    注意 只有显式的加载类 JVM才会加载到内存中 先加载父类的静态代码块 然后执行子类静态代码块 当前类存在类静态变量 注意引用类型没进行赋值操作初始化为null 并不会显式的加载类 又存在静态代码块 会先执行前者进行初始化 再执行静态代码块 在实例化类的时候 执行顺序

    2023年04月23日
    浏览(41)
  • 关于Java中代码的执行顺序

    注意 只有显式的加载类 JVM才会加载到内存中 先加载父类的静态代码块 然后执行子类静态代码块 当前类存在类静态变量 注意引用类型没进行赋值操作初始化为null 并不会显式的加载类 又存在静态代码块 会先执行前者进行初始化 再执行静态代码块 在实例化类的时候 执行顺序

    2023年04月23日
    浏览(33)
  • Java/Python/Go不同开发语言在进程、线程和协程的设计差异

    在多线程项目开发时,最常用、最常遇到的问题是 1,线程、协程安全 2,线程、协程间的通信和控制 本文主要探讨不同开发语言go、java、python在进程、线程和协程上的设计和开发方式的异同。 进程 进程是 操作系统进行资源分配的基本单位,每个进程都有自己的独立内存空

    2024年01月23日
    浏览(47)
  • java for循环内部使用线程

    2024年02月06日
    浏览(36)
  • JAVA多线程处理for循环数据

    对for循环内数据启用多线程执行,主线程与子线程无先后顺序 执行结果: 对for循环内数据启用多线程执行,主线程在所有子线程执行完成之后执行 执行结果: 对for循环内数据启用多线程执行,主线程在所有子线程执行完成之后执行 执行结果: 4. JAVA多线程10个线程处理100

    2024年02月11日
    浏览(53)
  • 【Java高级应用:深入探索Java编程的强大功能,JVM 类加载机制, JVM 内存模型,垃圾回收机制,JVM 字节码执行,异常处理机制】

    本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题 中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:

    2024年01月16日
    浏览(88)
  • 【Java】JVM执行流程、类加载过程和垃圾回收机制

    JVM,就是Java虚拟机,Java的的程序都是运行在JVM当中。 程序在执行之前先要把java源代码转换成字节码(class文件),JVM 首先需要把字节码通过一定的方(类加载器(ClassLoader)) 把文件加载到内存中的运行时数据区(Runtime Data Area) ,而字节码文件是 JVM 的一套指令集规范,并

    2024年02月16日
    浏览(48)
  • c++中 多线程执行时 线程的执行顺序不固定

            C++中多线程执行时,线程的执行顺序是不确定的。这是由于 多线程的并发性质 导致的。         在多线程程序中,多个线程可以同时执行,并且它们的执行顺序是由系统调度器决定的。系统调度器根据各种因素(如线程的优先级、线程的状态等)来决定何时

    2024年02月08日
    浏览(31)
  • java八股文面试[多线程]——并发三大特性 原子 可见 顺序

        AutomicInteger :  volatile + CAS 总线LOCK  MESI 两个协议 TODO volatile的可见性和禁止重排序是怎么实现的: DCL场景:  new操作会在字节码层面生成两个步骤: 分配内存、调用构造器 然后把引用赋值给singleton 不加volatile则会发生指令重排,可能得到不完整的对象 知识来源: 【并

    2024年02月11日
    浏览(49)
  • 深入探讨Java虚拟机(JVM):执行流程、内存管理和垃圾回收机制

    目录 什么是JVM? JVM 执行流程 JVM 运行时数据区 堆(线程共享) Java虚拟机栈(线程私有) 什么是线程私有? 程序计数器(线程私有) 方法区(线程共享) JDK 1.8 元空间的变化 运行时常量池 内存布局中的异常问题 1.  Java堆溢出 2.  虚拟机栈和本地方法栈溢出 JVM 类加载 1.

    2024年02月09日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包