前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java 主线程等待子线程执行完后再执行

java 主线程等待子线程执行完后再执行

作者头像
IT云清
发布2019-01-22 15:05:36
4.5K0
发布2019-01-22 15:05:36
举报
文章被收录于专栏:IT云清IT云清
这里记录一下下面这种情况:主线程需要等待多个子线程执行完后再执行。

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

代码语言:javascript
复制
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();
        }
    }

}

执行结果为:

代码语言:javascript
复制
主线程正在执行前: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(),代码示例如下:

代码语言:javascript
复制
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();
        }
    }

}

执行结果为:

代码语言:javascript
复制
主线程正在执行前:main
子线程正在执行:Thread-0
子线程正在执行:Thread-1
子线程正在执行:Thread-2
子线程正在执行:Thread-3
子线程正在执行:Thread-4
子线程正在执行:Thread-5
子线程正在执行:Thread-6
子线程正在执行:Thread-7
子线程正在执行:Thread-8
子线程正在执行:Thread-9
主线程正在执行后:main
或者用java8之前的方式写:
线程类:
代码语言:javascript
复制
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;
    }
}
测试类:
代码语言:javascript
复制
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());
    }

}
结果为:
代码语言:javascript
复制
主线程正在执行前:main
子线程正在执行任务,当前线程为:Thread-1
子线程正在执行任务,当前线程为:Thread-0
子线程正在执行任务,当前线程为:Thread-2
子线程正在执行任务,当前线程为:Thread-3
子线程正在执行任务,当前线程为:Thread-4
子线程正在执行任务,当前线程为:Thread-7
子线程正在执行任务,当前线程为:Thread-6
子线程正在执行任务,当前线程为:Thread-5
子线程正在执行任务,当前线程为:Thread-9
子线程正在执行任务,当前线程为:Thread-8
主线程正在执行后:main

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

代码语言:javascript
复制
    /**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();
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年07月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 这里记录一下下面这种情况:主线程需要等待多个子线程执行完后再执行。
  • 1.使用CountDownLatch
  • 或者用java8之前的方式写:
    • 线程类:
      • 测试类:
        • 结果为:
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档