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();
        }
    

      

  • 相关阅读:
    Android 解决小米手机Android Studio安装app 报错的问题It is possible that this issue is resolved by uninstalling an existi
    Android Unresolved Dependencies
    Android studio 自定义打包apk名
    Android Fragment与Activity交互的几种方式
    魅族和三星Galaxy 5.0webView 问题Android Crash Report
    Android几种常见的多渠道(批量)打包方式介绍
    Android批量打包 如何一秒内打完几百个apk渠道包
    上周热点回顾(9.30-10.6)团队
    上周热点回顾(9.23-9.29)团队
    上周热点回顾(9.16-9.22)团队
  • 原文地址:https://www.cnblogs.com/itzyz/p/11078374.html
Copyright © 2011-2022 走看看