java CountDownLatch用法 主线程等待子线程执行完后再执行
发布日期:2021-06-30 11:06:52 浏览次数:2 分类:技术文章

本文共 4582 字,大约阅读时间需要 15 分钟。

这里记录一下下面这种情况:主线程需要等待多个子线程执行完后再执行。

我们先看一下下面的场景:

package com.java4all.mypoint;import java.util.concurrent.CountDownLatch;/** * Author: yunqing * Date: 2018/7/18 * Description:线程测试 * 测试点:主线程等待子线程全部执行完后再执行 */public class ThreadTest {    public static void main(String[] args)throws Exception{        System.out.println("主线程正在执行前:"+Thread.currentThread().getName());        test3();        System.out.println("主线程正在执行后:"+Thread.currentThread().getName());    }    public static void test3(){        try {            for (int i = 1 ;i <= 10;i ++){                Thread.sleep(1000);                new Thread(()->{                    System.out.println("子线程正在执行:"+Thread.currentThread().getName());                }).start();            }        }catch (Exception ex){            ex.printStackTrace();        }    }}

执行结果为:

主线程正在执行前:main子线程正在执行:Thread-0子线程正在执行:Thread-1子线程正在执行:Thread-2子线程正在执行:Thread-3子线程正在执行:Thread-4子线程正在执行:Thread-5子线程正在执行:Thread-6子线程正在执行:Thread-7子线程正在执行:Thread-8主线程正在执行后:main子线程正在执行:Thread-9

可以看到,子线程还没执行完时,主线程进来了。

1.使用CountDownLatch

示例如下,我们初始化一个CountDownLatch,值为10(子线程个数),然后每次一个子线程执行完后执行一下countDown(),代码示例如下:

package com.java4all.mypoint;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;/** * Author: yunqing * Date: 2018/7/18 * Description:线程测试 * 测试点:主线程等待子线程全部执行完后再执行 */public class ThreadTest {    /**初始化CountDownLatch,值为线程数量*/    private static final CountDownLatch ctl = new CountDownLatch(10);        public static void main(String[] args)throws Exception{        System.out.println("主线程正在执行前:"+Thread.currentThread().getName());        test3();        ctl.await(20, TimeUnit.SECONDS);//最多等待20秒,不管子线程完没完        System.out.println("主线程正在执行后:"+Thread.currentThread().getName());    }    public static void test3(){        try {            for (int i = 1 ;i <= 10;i ++){                Thread.sleep(1000);                new Thread(()->{                    System.out.println("子线程正在执行:"+Thread.currentThread().getName());                }).start();                ctl.countDown();            }        }catch (Exception ex){            ex.printStackTrace();        }    }}

执行结果为:

主线程正在执行前:main子线程正在执行:Thread-0子线程正在执行:Thread-1子线程正在执行:Thread-2子线程正在执行:Thread-3子线程正在执行:Thread-4子线程正在执行:Thread-5子线程正在执行:Thread-6子线程正在执行:Thread-7子线程正在执行:Thread-8子线程正在执行:Thread-9主线程正在执行后:main

或者用java8之前的方式写:

线程类:
package com.java4all.mypoint;import java.util.concurrent.CountDownLatch;/** * Author: yunqing * Date: 2018/7/23 * Description: */public class MyRunnable implements Runnable{    public CountDownLatch countDownLatch;    @Override    public void run() {        try {            Thread.sleep(2000);            System.out.println("子线程正在执行任务,当前线程为:"+Thread.currentThread().getName());        }catch (InterruptedException inex){            inex.printStackTrace();        }finally {            countDownLatch.countDown();        }    }    public CountDownLatch getCountDownLatch() {        return countDownLatch;    }    public void setCountDownLatch(CountDownLatch countDownLatch) {        this.countDownLatch = countDownLatch;    }}
测试类:
package com.java4all.mypoint;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;/** * Author: yunqing * Date: 2018/7/18 * Description:线程测试 * 测试点:主线程等待子线程全部执行完后再执行 */public class ThreadTest {    /**初始化CountDownLatch,值为线程数量*/    private static final CountDownLatch ctl = new CountDownLatch(10);    public static void main(String[] args)throws Exception{        System.out.println("主线程正在执行前:"+Thread.currentThread().getName());        for(int i = 1;i <= 10;i ++){            MyRunnable runnable = new MyRunnable();            runnable.setCountDownLatch(ctl);            Thread thread = new Thread(runnable);            thread.start();        }        ctl.await(20, TimeUnit.SECONDS);//最多等待20秒,不管子线程完没完        System.out.println("主线程正在执行后:"+Thread.currentThread().getName());    }}
结果为:
主线程正在执行前:main子线程正在执行任务,当前线程为:Thread-1子线程正在执行任务,当前线程为:Thread-0子线程正在执行任务,当前线程为:Thread-2子线程正在执行任务,当前线程为:Thread-3子线程正在执行任务,当前线程为:Thread-4子线程正在执行任务,当前线程为:Thread-7子线程正在执行任务,当前线程为:Thread-6子线程正在执行任务,当前线程为:Thread-5子线程正在执行任务,当前线程为:Thread-9子线程正在执行任务,当前线程为:Thread-8主线程正在执行后:main

附:

开启一个线程的其他写法:

/**jdk7匿名内部类的写法*/    public static void test1(){        new Thread(new Runnable() {            @Override            public void run() {                System.out.println("aaaa");            }        }).start();    }    /**	 * jdk8	 * Runnable是个函数接口,可以利用jdk8的lambda来简写     * 函数接口:是指内部只有一个抽象方法的接口     * */    public static void test2(){        new Thread(()->{            System.out.println("bbb");        }).start();    }

转载地址:https://it4all.blog.csdn.net/article/details/81171731 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:git -- git merge合并分支
下一篇:java try with resources方式关闭资源

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月09日 13时40分56秒