zoukankan      html  css  js  c++  java
  • 多线程等待任务结束的几种方法

    比如,主线程创建线程池,提交n个任务,想让主线程在任务全部结束之后再继续做其他的事情。


    1、使用awaitTermination方法

    public static void main(String[] args) {
            ExecutorService executor = Executors.newFixedThreadPool(3);
            int i = 0;
            AtomicInteger result = new AtomicInteger(0);
            while (i < 10) {
                i++;
                executor.execute(() -> {
                    //每执行一次,对result加1
                    System.out.println(result.addAndGet(1));
                });
            }
            System.out.println("调用shutdown()方法时,result的值为:" + result.get());
            executor.shutdown();
            try {
                //等待所有任务结束,最多等待30分钟
                executor.awaitTermination(30, TimeUnit.MINUTES);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("计算完成,result的值为:" + result.get() + ",可以继续处理其他事情了");
        }
    

    boolean awaitTermination(long timeout, TimeUnit unit)的作用:

    Blocks until all tasks have completed execution after a shutdown request,
    or the timeout occurs, or the current thread is interrupted,
    whichever happens first.


    2、借助工具类CountDownLatch

    public static void main(String[] args) {
            ExecutorService executor = Executors.newFixedThreadPool(3);
            CountDownLatch latch = new CountDownLatch(10);
            AtomicInteger result = new AtomicInteger(0);
            for (int i = 1; i <= 10; i++) {
                executor.execute(() -> {
                    //do something...
                    System.out.println(result.addAndGet(1));
                    //then
                    latch.countDown();
                });
            }
            System.out.println("调用shutdown()方法时,result的值为:" + result.get());
            executor.shutdown();
            try {
                latch.await();//等待任务结束:其实是等待latch值为0
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println("计算完成,result的值为:" + result.get() + ",可以继续处理其他事情了");
    }
    

    适用于知道任务的数量,因为CountDownLatch在创建时就要指定其大小,并且不能重新初始化。

    //TODO:CountDownLatch是否会禁止指令重排序?(从官方的例子看,会!有待研究)

    public void example() {
            CountDownLatch doneSignal = new CountDownLatch(10);
            Executor e = Executors.newFixedThreadPool(10);
            for (int i = 0; i < 10; ++i) // create and start threads
                e.execute(new WorkerRunnable(doneSignal, i));
            try {
                doneSignal.await();           // wait for all to finis
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    
        class WorkerRunnable implements Runnable {
            private final CountDownLatch doneSignal;
            private final int i;
    
            WorkerRunnable(CountDownLatch doneSignal, int i) {
                this.doneSignal = doneSignal;
                this.i = i;
            }
    
            public void run() {
                doWork(i);
                doneSignal.countDown();
            }
    
            void doWork(int i) {
            }
        }
    

    其他

    //TODO



    作者:maxwellyue
    链接:https://www.jianshu.com/p/bcbfb58d0da5
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    python--模块与包
    内置函数 的总结
    迭代器 生成器 列表推导式 生成器表达式的一些总结
    函数的有用信息 带参数的装饰器 多个装饰器装饰一个函数
    函数名的应用(第一对象) 闭包 装饰器
    动态参数 名称空间 作用域 作用域链 加载顺序 函数的嵌套 global nonlocal 等的用法总结
    函数的初识 函数的返回值 参数
    文件操作 常用操作方法 文件的修改
    遍历字典的集中方法 集合的作用 以及增删查的方法
    计算机硬件的小知识
  • 原文地址:https://www.cnblogs.com/xiaoshen666/p/11258556.html
Copyright © 2011-2022 走看看