zoukankan      html  css  js  c++  java
  • JAVA中等待所有线程都执行结束(转2)

    场景:

    package com.java4all.mypoint;
    
    import java.util.concurrent.CountDownLatch;
    
    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;
    
    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;
    
    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();
        }
    

      

  • 相关阅读:
    Spark:大数据的“电光石火”
    Android开发-取消程序标题栏或自定义标题栏
    Android中实现圆角矩形及半透明效果。
    Android中设定背景图片平铺。
    收到的电邮附件为Winmail.dat?
    Runas命令:能让域用户/普通User用户以管理员身份运行指定程序。
    AD域服务器|两台DC无法进行复制同步
    IIS服务器运行一段时间后卡死,且无法打开网站(IIS管理无响应,必须重启电脑)
    Outlook不能打开附件(提示:无法创建文件xx,请右键单击要在其中创建文件的文件夹..)
    点击自动显示/隐藏DIV代码。(简单实用)
  • 原文地址:https://www.cnblogs.com/itzyz/p/11078374.html
Copyright © 2011-2022 走看看