美文网首页
多线程循环顺序处理的方式

多线程循环顺序处理的方式

作者: 名字是乱打的 | 来源:发表于2021-09-07 23:16 被阅读0次

目前有个任务需要对数据进行一个循环处理,那么就需要多线程顺序触发的问题了.
这里以顺序打印为例子对常见的多线程顺序处理做个总结,拿出两个非常常用的方式.

方法一: 资源+锁

核心点:
1.锁共同资源lock
2.通过while循环判断每次被唤醒是否要再次阻塞

public class ThreadsPrintOrder {
    private static Integer curr = 0;
    private static String[] strs = new String[]{"A", "B", "C"};
    private static int count = 10;
    static  Object lock=new Object();

    public static void main(String[] args) {
        final Thread a = getThread("A");
        final Thread b = getThread("B");
        final Thread c = getThread("C");

        a.start();
        b.start();
        c.start();
    }

    private static Thread getThread(String threadName) {
        return new Thread(() -> {
            synchronized (lock) {
                for (int i = 0; i < count; i++) {
                    while (!strs[curr%strs.length].equals(threadName)) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(Thread.currentThread().getName());
                    curr++;
                    lock.notifyAll();
                }
            }
        }, threadName);
    }
}

方法二 一个ReentrantLock加多个conditon实现(推荐,安全性,性能和可读性较高)

上面那种方法有个缺点就是每个线程被唤醒是随机的,每次被唤醒的可能是我们不想打印的线程,需要它再次自我关闭.
而ReentrantLock的独特效果可以做到结合conditon实现定向唤醒.

public class ThreadsPrintOrder_m2 {
    static int count=10;
    public static void main(String[] args) {
        LockOrderPrint lockOrder=new LockOrderPrint();
        new Thread(()->{
            for (int i = 0; i <count ; i++) {
                lockOrder.printA();
            }
        }).start();

        new Thread(()->{
            for (int i = 0; i <count ; i++) {
                lockOrder.printB();
            }
        }).start();

        new Thread(()->{
            for (int i = 0; i <count ; i++) {
                lockOrder.printC();
            }
        }).start();
    }
}

class LockOrderPrint {
    int flag=0;
    Lock lock=new ReentrantLock();
    Condition conditionA=lock.newCondition();
    Condition conditionB=lock.newCondition();
    Condition conditionC=lock.newCondition();

    public void printA(){
        lock.lock();
        try {
            while (flag%3!=0){
                try {
                    conditionA.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("A");
            flag++;
            conditionB.signal();

        }catch (Exception exce){
            exce.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void printB(){
        lock.lock();
        try {
            while (flag%3!=1){
                try {
                    conditionB.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("B");
            flag++;
            conditionC.signal();
        }catch (Exception exce){
            exce.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void printC(){
        lock.lock();
        try {
            while (flag%3!=2){
                try {
                    conditionC.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("C");
            flag++;
            conditionA.signal();
        }catch (Exception exce){
            exce.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

}

相关文章

  • 多线程循环顺序处理的方式

    目前有个任务需要对数据进行一个循环处理,那么就需要多线程顺序触发的问题了.这里以顺序打印为例子对常见的多线程顺序处...

  • 多线程顺序处理的方式

    目前有个任务需要对数据进行一个循环处理,那么就需要多线程顺序触发的问题了.这里以顺序打印为例子对常见的多线程顺序处...

  • 循环顺序打印

    通过Java多线程方式实现循环顺序打印A、B,而且保证无论多少次循环,都不乱序? 1. 问题描述 通过Java多线...

  • JavaScript 异步循环 - async/await 的使

    如何以顺序或并行方式运行异步循环? 在对循环进行异步处理之前,我想提醒您如何编写经典的同步循环。 同步循环 很久以...

  • 并发

    保证多线程的顺序执行 方式1:通过join方法保证多线程的顺序join作用:让主线程等待子线程结束后才能继续运行 ...

  • 2017-7-31 Shell脚本编程基础

    一.编程基本概念 编程逻辑处理方式: 顺序执行 循环执行 选择执行 shell编程:过程式、解释执行编程语言的基...

  • php多线程

    PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程。多线程在处理重复性的循环...

  • iOS 多线程之间有依赖时的处理方式

    iOS 多线程之间有依赖时的处理方式

  • 线性表之顺序表和链表(单/双链表,单/双循环链表)

    线性表按存储方式分为顺序表和链表两种,其中链表又分为单链表,循环链表,双链表,双向循环链表。 顺序表 顺序表采用顺...

  • 程序运行的基本结构

    基本的处理流程包含3种结构,即顺序结构、分支结构和循环结构。 1.顺序结构 顺序结构是程序按照线性顺序依次执行程序...

网友评论

      本文标题:多线程循环顺序处理的方式

      本文链接:https://www.haomeiwen.com/subject/otcpwltx.html