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

      

  • 相关阅读:
    03把IL编译成可执行文件
    02值类型
    报错:该字符串未被识别为有效的DateTime
    01使用ILDasm.exe将可执行文件反编译成IL代码
    MVC自定义路由02-实现IRouteConstraint限制控制器名
    MVC自定义路由01-为什么需要自定义路由
    报错:System.Data.Entity.Infrastructure.DbUpdateException 更新条目时出错
    输入网址背后发生的故事
    使用jquery加载部分视图02-使用$.ajax()
    使用jquery加载部分视图01-使用$.get()
  • 原文地址:https://www.cnblogs.com/itzyz/p/11078374.html
Copyright © 2011-2022 走看看