等待多个线程完成后执行其他任务2019-05-11

多线程之同步器:

假设有A,B 两个任务需要执行,A耗时3分钟,B耗时4分钟

常规方法是   

A();

B() ;

 ...    总耗时7分钟

但是如果想缩短时间,且A B在执行中没有对同一资源的争夺,那么

可以开启两个线程,分别执行A,B   Java提供了三种创建线程的方法

1 通过实现Runnable 接口;

2 通过继承Thread 类本身;

2 通过Callable和Future 创建线程。

此外,spring 可以通过TaskExcutor 任务执行器来实现多线程

线程1{ A() }

线程2{ B() }

...总耗时4分钟

进程会在开启两个进程执行A ,B后,继续执行接下来的代码而不必等待A B结束。

在一些情况下,我们接下来的代码(方法C)可能要用到A B 计算后的结果,那么该怎么设置程序等待A B 都运行结束呢?

线程同步器完美解决~

在JDK1.5以后,java.util.concurrent包提供了两个工具类CounDownLatch类和CyclicBarrier类。

CountDownLatch是一个同步计数器,能够保证在其他线程完成某一个业务操作前,当前线程一直处于等待/阻塞状态。具体来说,这个计数器将会从给定的某一个数值count开始,通过countDown()方法的调用进行倒数。当执行某一次countDown()操作后,计数器的count数值等于0,所有调用了await()方法的线程,就解除等待/阻塞状态继续执行。

// 同步计数器从2开始计数

finalCountDownLatch countDownLatch =newCountDownLatch(2);

// 启动子线程,处理A B

Thread childThreadA =newThread() {

        @Override

        public void run(){

                synchronized(this){

                        try{

                            A();

                        }catch(InterruptedException e) {

                               TestCountDownLatch.LOGGER.error(e.getMessage(), e);

                        }

            }

            // 完成业务处理过程,计数器-1

            countDownLatch.countDown();

        }

};

Thread childThreadB =newThread() {

        @Override

        public void run(){

synchronized(this){

                        try{

                            B();

                        }catch(InterruptedException e) {

                               TestCountDownLatch.LOGGER.error(e.getMessage(), e);

                        }

            }

            // 完成业务处理过程,计数器-1

            countDownLatch.countDown();

        }

};

childThreadA.start();

childThreadB.start();

// 等待所有子线程的业务都处理完成(计数器的count为0时) 

 countDownLatch.await();

c();

CyclicBarrier也是同步计数工具,不同的是CyclicBarrier的计数是循环进行的,而且也不需要向CountDownLatch那样显示的调用countDown进行减一操作。当CyclicBarrier的计数周期设置为n的时候,每当有n个进程进入阻塞等待,CyclicBarrier就解除这n个进程的阻塞状态。所以可以理解为CyclicBarrier的计数功能是可以重复使用的。

你可能感兴趣的:(等待多个线程完成后执行其他任务2019-05-11)