循环交替执行多线程任务-Java

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

1、循环打印-version1

/**
 * @author xin麒
 * @date 2023/7/21 23:04
 * 验证,如果有错,那么ctrl+f搜索false肯定会搜索到的!
 */
class XinTask{
    private final static Object lock = new Object();
    private int flag = 0;
    private int time;

    public XinTask(int time) {
        this.time = time;
    }

    public void print(int signal,int printTarget) {

        for (int i = 0; i < time; i++) {
            synchronized (lock){
                while (flag != signal){
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(flag + " printTarget == flag ? " + (printTarget == flag));
                flag = (flag + 1) % 3;
                lock.notifyAll();
            }
        }
    }
}

public class Main {
    static private XinTask xinTask = new XinTask(10000);
    public static void main(String[] args) {

        new Thread(()->{
            xinTask.print(0,0);
        },"task0").start();

        new Thread(()->{
            xinTask.print(1,1);
        },"task1").start();

        new Thread(()->{
            xinTask.print(2,2);
        },"task2").start();

    }
}

2、循环打印-version2

/**
 * @author xin麒
 * @date 2023/7/21 23:04
 * 验证,如果有错,那么再控制台终端ctrl+f搜索false肯定会搜索到的!
 */
class XinTask {
    private int flag = 0;
    private int time;
    int queueNumber;

    public XinTask(int queueNumber) {//如果是走这个构造方法,那么则执行一遍
        this.queueNumber = queueNumber;
        time = 1;
    }

    public XinTask(int time, int queueNumber) {//如果是走这个构造方法,那么则循环time次
        this.time = time;
        this.queueNumber = queueNumber;
    }

    public void print(String targetStr, int signal) {

        for (int i = 0; i < time; i++) {
            synchronized (this) {
                while (flag != signal) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("targetStr is " + targetStr + " ,flag is " + flag + " , signal == flag ? " + (signal == flag));
                flag = (flag + 1) % queueNumber;
                this.notifyAll();
            }
        }
    }
}

public class Main {
    static final int queueNumber = 3;
    private static final int time = 10000;
    static private XinTask xinTask = new XinTask(time, queueNumber);//只能循环执行queueNumber个线程的内容。按照线程创建且实例化的顺序来执行

    public static void main(String[] args) {
        new Thread(() -> {
            xinTask.print("a", 0);
        }, "task0").start();//实例化第一个线程

        new Thread(() -> {
            xinTask.print("b", 1);
        }, "task1").start();//实例化第2个线程

        new Thread(() -> {
            xinTask.print("c", 2);
        }, "task2").start();//实例化第3个线程

    }

    @Test
    public void test() {
        ArrayList<String> list = new ArrayList<>(queueNumber);
        list.add("a");
        list.add("b");
        list.add("c");
        printTargetStringByThreads(list);
    }

    private void printTargetStringByThreads(ArrayList<String> list) {//按照list里面的节点的顺序打印节点里存储的数据
        ArrayList<Thread> threads = new ArrayList<>(queueNumber);
        for (int i = 0; i < queueNumber; i++) {
            int order = i;
            Thread t = new Thread(() -> {
                xinTask.print(list.get(order) + "", order);
            }, "task" + order);
            t.start();
            threads.add(t);
        }

        threads.forEach((t) -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
}

3、最终版本

import org.junit.Test;

import java.util.ArrayList;

/**
 * @author xin麒
 * @date 2023/7/21 23:04
 */
class XinTask {
    private int flag = 0;
    private int time;

    public XinTask() {
        time = 1;
    }

    public XinTask(int time) {//如果是走这个构造方法,那么则循环time次
        this.time = time;
    }

    public void print(String targetStr, int signal, int queueNumber) {

        for (int i = 0; i < time; i++) {
            synchronized (this) {
                while (flag != signal) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("targetStr is " + targetStr);//如果不需要其他提示也可以改成:
//                System.out.print( targetStr);
                flag = (flag + 1) % queueNumber;
                this.notifyAll();
            }
        }
    }

    public void printTargetStringByThreadsWithJoin(ArrayList<String> list) {//按照list里面的节点的顺序打印节点里存储的数据
        if (list == null) return;
        ArrayList<Thread> threads = new ArrayList<>(list.size());
        for (int i = 0; i < list.size(); i++) {
            int order = i;
            Thread t = new Thread(() -> {
                print(list.get(order), order, list.size());
            }, "task" + order);
            t.start();
            threads.add(t);
        }

        threads.forEach((t) -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
}

public class Main {
    private static final int time = 10000;
    static private XinTask xinTask = new XinTask(time);//只能循环执行queueNumber个线程的内容。按照线程创建且实例化的顺序来执行

    public static void main(String[] args) {
        new Thread(() -> {
            xinTask.print("a", 0, 3);
        }, "task0").start();//实例化第一个线程

        new Thread(() -> {
            xinTask.print("b", 1, 3);
        }, "task1").start();//实例化第2个线程

        new Thread(() -> {
            xinTask.print("c", 2, 3);
        }, "task2").start();//实例化第3个线程

    }

    @Test
    public void test() {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        XinTask xinTask = new XinTask(10000);
        xinTask.printTargetStringByThreadsWithJoin(list);//按照list节点数据的存放顺序来打印
    }

}

文章来源地址https://www.toymoban.com/news/detail-600441.html

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

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

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

相关文章

  • java线程-synchronized详解

    解决线程原子性问题,最常见的手段就是加锁,Java提供了两种加锁的方式,一个synchronized隐式锁,另外一个是通过J.U.C框架提供的Lock显式加锁。本文主要介绍一个Synchronized的实现方式。 synchronized解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是

    2024年02月10日
    浏览(38)
  • java八股文面试[多线程]——两个线程交替打印1-100之间的数字

    一份代码,两个线程,使用synchronize实现: 重写run()方法,将输出1到100之间整数的代码写到同步方法里。 线程1进入到同步方法,输出一个整数后,阻塞并释放锁。 线程2进入到同步方法,唤醒线程1,输出整数后,阻塞并释放锁。 线程1和线程2重复第3步,直到输出所有的整数

    2024年02月11日
    浏览(33)
  • 多线程知识:三个线程如何交替打印ABC循环100次

    本文博主给大家讲解一道网上非常经典的多线程面试题目。关于三个线程如何交替打印ABC循环100次的问题。 下文实现代码都基于Java代码在单个JVM内实现。 给定三个线程,分别命名为A、B、C,要求这三个线程按照顺序交替打印ABC,每个字母打印100次,最终输出结果为: 推荐博

    2024年02月12日
    浏览(66)
  • Java多线程(二)——synchronized 详解

    目录 1 volatile 1.1保证变量可见性 1.2 不能保证数据的原子性举例 1.3 禁止JVM指令重排序 2 synchronized 2.1 概念及演进 2.2 对象锁和类锁 2.3 synchronized 的用法分类 2.4 synchronized 的用法详解 2.5 synchronized总结+补充 3 synchronized 底层原理 3.1 synchronized 同步语句块的情况

    2024年02月13日
    浏览(30)
  • Synchronized与Java线程的关系

    ​ Java多线程处理任务时,为了线程安全,通常会对共享资源进行加锁,拿到锁的线程才能进行访问共享资源。而加锁方式通过都是Synchronized锁或者Lock锁。 ​ 那么多线程在协同工作的时候,线程状态的变化都与锁对象有关系。 ​ Java采用synchronized、以互斥同步的方式

    2024年02月11日
    浏览(24)
  • Java关键字之synchronized详解【Java多线程必备】

    点击   Mr.绵羊的知识星球  解锁更多优质文章。 目录 一、介绍 二、特性 1. 线程安全 2. 互斥访问 3. 可重入性 4. 内置锁 三、实现原理 四、和其他锁比较 1. 优点 2. 缺点 五、注意事项和最佳实践 六、使用案例 1. 案例一 2. 案例二     synchronized是Java中最基本的同步机制之一,

    2024年01月24日
    浏览(36)
  • Java多线程篇(1)——深入分析synchronized

    synchronized实现原理的由浅入深依次为 字节码层面:monitorenter/monitorexit 指令 java对象层面: Mark Word 对象头 JVM层面: CAS、自旋 、 ObjectMonitor(MESA管层模型:cxq,entryList,wait三个队列) 操作系统层面: mutex 锁 其中 mark word 对象头如下图: 说到锁升级,我相信很多人都错

    2024年02月09日
    浏览(29)
  • C# 多线程交替按照指定顺序执行

    1.关于AutoResetEvent和ManualResetEvent的区别解释如下: AutoResetEvent和ManualResetEvent是.NET中的两个线程同步类。它们之间的主要区别在于其释放信号的方式以及对等待线程的影响。 AutoResetEvent的作用是在等待的线程被信号唤醒后,将信号自动重置为非终止状态。也就是说,当一个线程

    2024年02月11日
    浏览(25)
  • 【Java|多线程与高并发】线程安全问题以及synchronized使用实例

    Java多线程环境下,多个线程同时访问共享资源时可能出现的数据竞争和不一致的情况。 线程安全一直都是一个令人头疼的问题.为了解决这个问题,Java为我们提供了很多方式. synchronized、ReentrantLock类等。 使用线程安全的数据结构,例如ConcurrentHashMap、ConcurrentLinkedQueue等

    2024年02月09日
    浏览(32)
  • Java并发编程(三)线程同步 上[synchronized/volatile]

    当使用多个线程来访问同一个数据时,将会导致数据不准确,相互之间产生冲突,非常容易出现线程安全问题,比如多个线程都在操作同一数据,都打算修改商品库存,这样就会导致数据不一致的问题。 所以我们通过线程同步机制来保证线程安全,加入同步锁以避免在该线程没有完成

    2024年02月13日
    浏览(30)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包