循环交替执行多线程任务-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节点数据的存放顺序来打印
    }

}

你可能感兴趣的:(java,锁,java,多线程,轮询,synchronized,锁)