美文网首页
等待多个线程完成后执行其他任务2019-05-11

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

作者: yogoshary | 来源:发表于2019-05-11 13:40 被阅读0次

    多线程之同步器:

    假设有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

          本文链接:https://www.haomeiwen.com/subject/bclxaqtx.html