精华内容
下载资源
问答
  • Java等待线程执行完毕

    千次阅读 2017-07-18 23:10:27
    前言:前一段时间在做项目的时候,某段代码中用到了多线程,该处代码需要开启多个线程,待这几个线程执行完毕后再接着执行后续的流程。现将可采用的方法记录如下。 要达到上述的描述的情形,可以使用Thread的join()...

    前言:前一段时间在做项目的时候,某段代码中用到了多线程,该处代码需要开启多个线程,待这几个线程执行完毕后再接着执行后续的流程。现将可采用的方法记录如下。


    要达到上述的描述的情形,可以使用Thread的join()方法,也可以使用java.util.concurrent包中的CountDownLatch类。具体如下:

    一、使用Thread.join()方法

    该方法在JDK API中的解释为“等待该线程终止”,存在三个方法重载,如下:
    void join();
    void join(long millis); // 等待该线程终止的最长时间为millis毫秒
    void join(long millis, int nanos); // 等待该线程终止的最长时间为millis毫秒+nanos纳秒

    代码如下:

    package threadTest;
    
    import java.util.Vector;
    import java.util.concurrent.*;
    
    /**
     * Created by worm0527 on 2017/7/17.
     */
    public class ThreadTest extends Thread {
    
        // 线程名称
        private String threadName;
    
        // 线程休眠时间
        private int sleepSec;
    
        ThreadTest(String threadName, int sleepSec) {
            super(threadName);
            this.sleepSec = sleepSec;
            start();// 在构造方法中启动线程
        }
    
        @Override
        public void run() {
            long starttime = System.currentTimeMillis();
            System.out.println(Thread.currentThread().getName() + " running...");
            try {
                // 休眠制定时间(单位:秒)
                TimeUnit.SECONDS.sleep(sleepSec);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " run at " + (System.currentTimeMillis() - starttime) + " ms");
        }
    
        public static void main(String[] args) throws InterruptedException {
    
            long starttime = System.currentTimeMillis();
            System.out.println("Thread main running...");
    
            Vector<Thread> threadVector = new Vector<Thread>();
            for (int i = 1; i < 5; i++) { // 开启四个线程
                Thread t = new ThreadTest("Thread" + i, i);
                threadVector.add(t);
            }
    
            for (Thread t : threadVector) { // 循环调用线程join()方法,等待线程结束
                t.join();
            }
    
            System.out.println("Thread main End");
            System.out.println("Thread main run at " + (System.currentTimeMillis() - starttime) + " ms");
        }
    }
    

    运行结果:

    运行结果

    二、使用CountDownLatch类

    主要使用了该类的await()和countDown()两个方法。await()阻塞线程,直到计数器归零或者线程被中断,调用countDown()来递减计数器。

    代码如下:

    package threadTest;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Created by worm0527 on 2017/7/18.
     */
    public class ThreadTest1 extends Thread {
    
        // 线程名称
        private String threadName;
    
        // 线程休眠时间
        private int sleepSec;
    
        private CountDownLatch latch; // 线程类中持有CountDownLatch对象的引用
    
        public ThreadTest1(String threadName, int sleepSec, CountDownLatch latch) {
            super(threadName);
            this.sleepSec = sleepSec;
            this.latch = latch;
            start();// 在构造方法中启动线程
        }
    
        @Override
        public void run() {
            long starttime = System.currentTimeMillis();
            System.out.println(Thread.currentThread().getName() + " running...");
            try {
                // 休眠制定时间(单位:秒)
                TimeUnit.SECONDS.sleep(sleepSec);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " run at " + (System.currentTimeMillis() - starttime) + " ms");
            latch.countDown();
        }
    
        public static void main(String[] args) throws InterruptedException {
    
            long starttime = System.currentTimeMillis();
            System.out.println("Thread main running...");
    
            CountDownLatch latch = new CountDownLatch(4); // 共四个子线程
            for (int i = 1; i < 5; i++) {
                new ThreadTest1("Thread" + i, i, latch);
            }
            latch.await(); // 阻塞,直到线程计数归零
    
            System.out.println("Thread main End");
            System.out.println("Thread main run at " + (System.currentTimeMillis() - starttime) + " ms");
        }
    
    }
    

    运行结果:

    运行结果

    展开全文
  • Java线程--等待所有子线程执行完的五种方法 Java线程--等待所有子线程执行完的五种方法 Java线程--等待所有子线程执行完的五种方法 Java线程--等待所有子线程执行完的五种方法 Java线程--等待所有子线程...
  •  数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis()在后一个子进程结束后...
  • 简单总结两种实现方式: 一、应用 Callable();二、利用计数器 egg: 一、应用 Callable() ...ExecutorService executorService ...// ... 线程执行程序 ..."线程执行完毕!" ) ; // 执行后续程序

    简单总结两种实现方式:
    一、应用 Callable();二、利用计数器
    egg:

    一、应用 Callable()

    // 创建线程池
    ExecutorService executorService = Executors.newFixedThreadPool(6);
    List<FutureTask<Object>> futureTasks = new ArrayList<FutureTask<Object>>();
    futureTasks.add(new FutureTask<>(new Callable<Object>() {
                @Override
                public String call() {
                    // 线程1执行程序
                    return "线程1返回结果";
                }
            }));
    futureTasks.add(new FutureTask<>(new Callable<Object>() {
                @Override
                public String call() {
                    // 线程2执行程序
                    return "线程2返回结果";
                }
            }));
    // 加入 线程池		
    for (FutureTask<Object> futureTask : futureTasks) {
                executorService.submit(futureTask);
            }
    
    // 获取线程返回结果
    for (int i = 0; i < futureTasks.size(); i++) {
    	try {
    		String flag = (String) futureTasks.get(i).get();
    		log.info(flag);
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }
    // 执行后续程序
    

    二、利用计数器

    // 创建线程
    public class RetailerResultAllocationThread implements Runnable {
        private List<RetailerCalculationResultAllocationVo> resultAllocationVos;
        private CountDownLatch latch;
    
        public RetailerResultAllocationThread(List<RetailerCalculationResultAllocationVo> resultAllocationVos, CountDownLatch latch){
            this.resultAllocationVos = resultAllocationVos;
            this.latch = latch;
        }
    
        @Override
        public void run() {
            // ... 线程执行程序
    		// 计数器计数
            latch.countDown();
        }
    }
    
    // 创建线程池
    ExecutorService executorService = Executors.newFixedThreadPool(4);
    try {
    	List<List<RetailerCalculationResultAllocationVo>> list = new ArrayList<>();
    	// 创建计数器
        CountDownLatch latch = new CountDownLatch(list.size());
        for (List<RetailerCalculationResultAllocationVo> resultAllocationVos : list) {
            executorService.submit(new RetailerResultAllocationThread(resultAllocationVos, latch));
        }
        // 等待 更新线程更新完再落地数据
        latch.await();
    } catch (InterruptedException e) {
        log.error(e.getMessage());
    }finally {
        if(executorService != null && !executorService.isShutdown()){
            executorService.shutdown();
        }
    }
    	
    log.info("线程执行完毕!");
    // 执行后续程序
    
    展开全文
  • java 等待线程/线程池执行完毕

    千次阅读 2017-08-07 15:43:54
    1.单线程开始并执行完毕线程开始后,需要用到join的方法 不废话直接贴代码 public static void main(String args[]) { long begin = System.currentTimeMillis(); System.out.println(begin); Thread thread...

    1.单线程开始并执行完毕
    当线程开始后,需要用到join的方法
    不废话直接贴代码

       public static void main(String args[]) {
            long begin = System.currentTimeMillis();
            System.out.println(begin);
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("111");
                }
            });
            try {
                thread.start();
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long end = System.currentTimeMillis();
            System.out.println(end-begin);
            System.out.println("执行完毕");
        }

    运行结果:

    1502091332017
    111
    1002
    执行完毕

    现在我们来看一下join这个方法

        /**
         * Waits for this thread to die.
         *
         * <p> An invocation of this method behaves in exactly the same
         * way as the invocation
         *
         * <blockquote>
         * {@linkplain #join(long) join}{@code (0)}
         * </blockquote>
         *
         * @throws  InterruptedException
         *          if any thread has interrupted the current thread. The
         *          <i>interrupted status</i> of the current thread is
         *          cleared when this exception is thrown.
         */
        public final void join() throws InterruptedException {
            join(0);
        }
        翻译为中文大意就是,等待线程执行完毕!

    2.等待线程池执行完毕
    等待线程池执行完毕我们需要用到
    CountDownLatch这个类
    且看代码:

        public static void main(String args[]) throws InterruptedException {
            final CountDownLatch count = new CountDownLatch(3);
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
            try {
                long begin = System.currentTimeMillis();
                System.out.println(begin);
                fixedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1000L);
                            count.countDown();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("111");
                    }
                });
                fixedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000L);
                            count.countDown();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("222");
                    }
                });
                fixedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(3000L);
                            count.countDown();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("333");
                    }
                });
    
                count.await();
                long end = System.currentTimeMillis();
                System.out.println(end-begin);
                System.out.println("执行完毕");
            } finally {
                fixedThreadPool.shutdown();
            }
        }

    最后一定要记得线程池关闭, 要不会出大问题的
    运行结果:

    1502091739441
    111
    222
    333
    3002
    执行完毕
    展开全文
  • Java主线程等待所有子线程执行完毕执行,其实在我们的工作中经常的用到,本篇文章就介绍了Java线程--让主线程等待所有子线程执行完毕执行,有需要的可以了解一下。
  • java 等待所有线程执行完毕

    千次阅读 2017-01-22 16:34:55
    问题的由来主线程等待所有线程运行完后,再执行逻辑,这个需求很普遍。比如,在处理数据时,为了效率期间,起了10个线程,分别处理一块数据,这样能缩短处理时间,10个线程执行完后,继续进行下边的逻辑(有点...

    #问题的由来
    主线程等待所有线程都运行完后,再执行逻辑,这个需求很普遍。比如,在处理数据时,为了效率期间,起了10个线程,分别处理一块数据,这样能缩短处理时间,10个线程都执行完后,继续进行下边的逻辑(有点map/reduce的意思)。这里我们就需要用到java的线程同步类 CountDownLatch ,count down是计数的意思,latch是门闩的意思,合起来也就是计数的开关。我们看一下CountDownLatch的API。

    #CountDownLatch API介绍

    一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

    用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await
    方法会一直受阻塞。之后,会释放所有等待的线程,await
    的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。

    CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的 CountDownLatch
    用作一个简单的开/关锁存器,或入口:在通过调用 countDown() 的线程打开入口前,所有调用 await 的线程都一直在入口处等待。用
    N 初始化的 CountDownLatch 可以使一个线程在 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N
    次之前一直等待。

    CountDownLatch 的一个有用特性是,它不要求调用 countDown
    方法的线程等到计数到达零时才继续,而在所有线程都能通过之前,它只是阻止任何线程继续通过一个 await。

    从中可以看出,最重要的几个步骤,

    第一,创建门闩,
    
    第二,开启门闩,阻塞所有线程,
    
    第三,其它线程递减次数,减为0时,门闩打开,主线程继续执行放开门闩
    

    #样例

    public class TestCountDownLatch {
    
    	
    	public static void main(String[] args) {
    		
    		int count = 5;
    		final CountDownLatch latch = new CountDownLatch(count);//创建门闩
    		
    		//execute thread
    		for(int i=0; i<count; i++){
    			new Thread(new Worker(latch)).start();
    		}
    		//
    		System.out.println("进入等待");
    		
    		
    		try {
    			latch.await();//开启门闩,阻塞所有线程,
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		
    		//dosomething
    		System.out.println("都执行完了");
    	}
    	
    	
    	
    }
    
    class Worker implements Runnable{
    	
    	private final CountDownLatch latch;
    	
    	
    	
    	public Worker(CountDownLatch latch) {
    		super();
    		this.latch = latch;
    	}
    	
    	
    	
    	@Override
    	public void run() {
    		
    		
    		//do something
    		System.out.println(Thread.currentThread().getName());
    		
    		try {
    			Thread.sleep(5000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		
    		/*
    		其它线程递减次数,减为0时,门闩打开,主线程继续执行放开门闩。
    		每调用一次countdown()计数就减一次
    		*/
    		latch.countDown();//递减
    	}
    	
    	
    }
    

    输出结果

    这里写图片描述

    #后续
    这里,我们没有往线程中传值、也没有获取线程的计算结果,所以比较简单。如果需要往线程中传值,使用构造函数方法传参或者公共方法传参;获取其它线程的计算结果,可以使用Future

    展开全文
  • 常用的两种方式: 第一种方式:来自大神... } catch (InterruptedException E) { // handle } 然后在线程方法中加入 try { ... } catch (Exception e) { e.printStackTrace(); }finally { countDownLatch.countDown(); }
  • Java线程--让主线程等待所有子线程执行完毕
  • Java并发线程控制:CountDownLatch等待所有线程运行完毕执行 创建一批Java线程,然后这批Java线程几乎同时全部跑起来,但是有些开发场景下,开发者需要等到这些Java线程全部执行完毕后,才去执行接下去的业务...
  • 非常实用不解释,用了才知道 个人收藏的一部分资料将陆续给大家上传
  • java主线程等待所有子线程执行完毕执行

    万次阅读 多人点赞 2018-07-18 21:00:06
    java主线程等待所有子线程执行完毕执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程执行,所有处理完成了之后才会返回给用户...
  • 在实际开发过过程中,我们会经常...待所有子线程的任务完成之后,在运行后续的业务,或者退出Main线程。代码如下:WorkThread.javapublic class WorkThread extends Thread { @Override public void run() { try {
  • 使用Java多线程编程时经常遇到主线程需要等待线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待。 CountDownLatch是一个同步辅助工具,用于使一个或多个线程等待(即阻塞)知道一组在...
  • 每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。 案例: public static void test2() throws InterruptedException { ...
  • Java线程池: 等待所有线程执行完成

    千次阅读 2020-12-25 15:40:08
    } } 执行结果 hello281 执行线程..test-pool-2 hello550 执行线程..test-pool-3 hello671 执行线程..test-pool-4 hello1041 执行线程..test-pool-1 hello813 执行线程..test-pool-3 hello981 执行线程..test-pool-1...
  • 执行前面所有的线程后再执行后续逻辑 代码如下: WorkThread.java public class WorkThread extends Thread { @Override public void run() { try { System.out.println(getName() + &amp;quot;run...
  • 实际开发中,经常会碰到这种问题,某个线程需要等待所有的线程执行结束了,才可以继续执行。要实现这个效果,Java中有很多方案,下面我列举一些我所知道的方案: 方案一:join。代码如下: Thread thread1=new ...
  • JAVA主线程等待线程执行完毕再执行[参照].pdf
  • 1.使用 CountDownLatch ,每个线程完成后都去将计数器减一,最后完成时再来唤醒主线程. 代码示例: public class testThreadSync3{ public static void main(String[] args) { final Vector<Integer> list = ...
  • 此前被面试问道一道面试题,B,C线程都有自己的任务,A线程要在B,C线程都结束后开始执行,并且不允许有A线程循环等待空耗CPU现象。
  • 1. 等待一个子线程执行完毕 public static void main(String[] args) { ExecutorService threadPool = Executors.newSingleThreadExecutor(); Future<String> future = threadPool.submit( new ...
  • 专栏原创出处:github-源笔记文件 ,github-源码 ,欢迎 Star,转载请附上原文出处链接和本声明。...CountDownLatch 允许一个或多个线程等待其他线程完成操作。 CountDownLatch 如何使用 CountDownLatch 的构...
  • java主线程等待所有子线程执行完毕执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程执行,所有处理完成了之后才会返回给用户...
  • 当任务量较大时,我们需要开启线程执行任务,但是在一些特定需求下,我们需要在全部任务执行后获取执行结束标识等信息,此时就需要判断任务分配的线程是否全部结束。 目录: 四程池 判断线程是否全部执行完毕...
  • Java主线程等待所有子线程执行完毕执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程执行,所有处理完成了之后才会返回给用户...
  • ????使用 ThreadGroup,首先创建一个线程组,把创建的子线程都放到这个线程组里,然后循环判断这个线程组的活跃线程数量 是否等于0,不等于0继续,否则代表子线程全部执行完了,进行下一步。
  • 最近有个项目需求是线程池子线程进行数据处理、入库,所有子线程运行完成之后需要汇总子线程运行数据。这里简单介绍一下主线程等待线程结束的集中方式

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 115,523
精华内容 46,209
关键字:

java等待线程执行完毕

java 订阅