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

      

  • 相关阅读:
    电源跳闸或突然断电后Kafka启动失败问题
    Failure to find org.glassfish:javax.el:pom:3.0.1b06SNAPSHOT
    Idea中的maven工程运行Scala报Command execution failed
    Scala(一)入门
    HBase2.0.5
    GridView之CommandField的妙用——点击提示删除
    SharePoint 2010在新窗口打开文档库中的文件
    SharePoint 2010 使用后台代码向SP.UI.ModalDialog.showModalDialog传值
    SharePoint 2010 使用代码创建视图查询条件
    Sharepoint 2010 禁止用户在文档库的第一级(根)目录上传文件
  • 原文地址:https://www.cnblogs.com/itzyz/p/11078374.html
Copyright © 2011-2022 走看看