• 【java】【多线程】等待开启的多个线程都执行完成,再做事情,怎么实现


    今天在controller中写一个接口用来测试模拟多个请求同时到达 下订单的情况,

    怎么能有效保证高并发下的库存和销量的一致性呢?【具体实现方法:https://www.cnblogs.com/sxdcgaq8080/p/9454161.html

    ====

    那么好,在这个接口中,开启多线程模拟了多个用户请求同时到达的状况,现在想在多个线程都执行完了以后再统一返回结果给前台,哪些请求成功了,哪些请求失败了。

    ====

    所以现在的需求是怎么能实现 等待多个线程都执行完了以后再做事情~~~

    ===================================================================================================================================

    其实想要实现这个需求:等待多个线程执行完了,再做事情。

    有两种方法,可以应对不同的情况:

    分别是CountDownLatchCyclicBarrier

    ===================================================================================================================================

    CountDownLatch和CyclicBarrier简单比较:

     

    CountDownLatch

    CyclicBarrier

    软件包

    java.util.concurrent

    java.util.concurrent

    适用情景

    主线程等待多个工作线程结束

    多个线程之间互相等待,直到所有线程达到一个障碍点(Barrier point)

    主要方法

    CountDownLatch(int count) (主线程调用)

    初始化计数

    CountDownLatch.await (主线程调用)

    阻塞,直到等待计数为0解除阻塞

    CountDownLatch.countDown

    计数减一(工作线程调用)

    CyclicBarrier(int parties, Runnable barrierAction) //初始化参与者数量和障碍点执行Action,Action可选。由主线程初始化

    CyclicBarrier.await() //由参与者调用

    阻塞,直到所有线程达到屏障点

    等待结束

    各线程之间不再互相影响,可以继续做自己的事情。不再执行下一个目标工作。

    在屏障点达到后,允许所有线程继续执行,达到下一个目标。可以重复使用CyclicBarrier

    异常

    如果其中一个线程由于中断,错误,或超时导致永久离开屏障点,其他线程也将抛出异常。

    其他

    如果BarrierAction不依赖于任何Party中的所有线程,那么在任何party中的一个线程被释放的时候,可以直接运行这个Action。

    If(barrier.await()==2)

    {

    //do action

    }

    CountDownLatch 使用示例代码:

    主线程调用

    工作线程调用

    复制代码
    package com.sxd.swapping.utils;
    
    import org.junit.Test;
    
    import java.util.concurrent.CountDownLatch;
    
    public class ThreadTest {
    
    
        /**
         * 主线程
         */
        @Test
        public  void  test(){
    
            //开启10个多线程
            int threadCount = 10;
    
            //所有线程阻塞,然后统一开始
            CountDownLatch begin = new CountDownLatch(1);
    
            //主线程阻塞,直到所有分线程执行完毕
            CountDownLatch end = new CountDownLatch(threadCount);
    
            //开始多线程
            begin.countDown();
            for (Integer i = 0; i < threadCount; i++) {
                Runnable runnable = dealSomeThing(i,begin,end);
                new Thread(runnable).start();
            }
    
            //多个线程都执行结束
            try {
                end.await();
                System.out.println("多个线程都执行结束,可以做自己的事情了");
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("多线程执行中出错了,凉凉了!!!");
            }
        }
    
    
        /**
         * 工作线程
         * 本方法  是在构造多线程要做的事情
         *
         * =====================可以做的事===================
         * 当然可以传入ConcurrentHashMap之类的线程安全的 类
         * 来记录线程中的处理结果之类的
         * 最后 在多线程都执行完了以后 就可以对处理结果进行操作了
         * ==================================================
         *
         * @param threadNum 当前线程编号
         * @param begin
         * @param end
         * @return
         */
        private Runnable dealSomeThing(int threadNum, CountDownLatch begin, CountDownLatch end){
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
    
                    try {
                        System.out.println("线程"+threadNum+":--------------------->开始工作");
                        begin.await();
    
                        System.out.println("线程"+threadNum+"做具体的事情,比如去service调用 具体的方法做什么操作之类的");
    
                        end.countDown();
                        System.out.println("线程"+threadNum+":--------------------->结束工作");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                }
            };
            return runnable;
        }
    
    
    
    
    }
    复制代码

    最后实现的结果:

    =========================================================================================

  • 相关阅读:
    关于重构之Switch的处理【二】
    转,有用
    C#枚举总结和其扩展用法(通过枚举描设置枚举值)
    DataGridView编辑状态和CurrentCellDirtyStateChanged
    C#获取DataGirdView选定子项子控件类型,is,as的用法
    VS2013添加作者注释(C#工程)
    开通博客了 zkh
    CentOS7下在线安装mysql zkh
    设计模式之简单工厂,工厂方法,抽象工厂模式(二) zkh
    asp.net mvc中捕获异常和使用log4net日志记录组件 zkh
  • 原文地址:https://www.cnblogs.com/telwanggs/p/13979532.html
Copyright © 2020-2023  润新知