美文网首页
等待多线程完成 - CountDownLatch

等待多线程完成 - CountDownLatch

作者: zbsong | 来源:发表于2020-07-06 19:17 被阅读0次

什么是CountDownLatch?

一种同步辅助工具,允许一个或多个线程等待其他线程中正在执行的一组操作
完成。

初始化CountDownLatch时传入一个int类型的参数作为计数器,比如传入N,在当在线程中调用CountDownLatch的await方法时,会阻塞当前线程,当在线程中调用CountDownLatch的countDown方法时,N(计数器)减1,当N变成0时,将会释放所有等待的线程,任何后续的await调用都将立即返回。

注意

1、创建CountDownLatch时,计数器必须大于0,等于0时,调用await方法不会阻塞线程。
2、CountDownLatch不能重新初始化或者修改CountDownLatch对象的内部计数器的值。如果需要使用重置计数器的功能,可以考虑使用CyclicBarrier。

CountDownLatch方法

类型 方法 描述
void await() 使当前线程等待闩锁倒数为零,或者线程被中断
boolean await(long timeout, TimeUnit unit) 使当前线程等待闩锁倒数为零,或者超时
void countDown() 减少闩锁的计数,如果计数为零,则释放所有等待的线程
long getCount() 返回当前计数
String toString() 返回标识此闩锁的字符串及其状态

例子

package com.sy.thread.example;

import java.util.concurrent.CountDownLatch;

/**
 * Description: thread
 *
 * @author songyu
 */
public class CountDwonLatchTest {
    /**
     * 创建CountDownLatch,计数器设置为2
     */
    private static CountDownLatch countDownLatch = new CountDownLatch(2);

    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("1");
                //计数器-1
                countDownLatch.countDown();
            }
        }).start();
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("2");
                    //等待2秒
                    Thread.sleep(2000);
                    //计数器-1,countDownLatch的计数器变为0,阻塞线程继续执行
                    countDownLatch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        //调用await()阻塞当前线程,直到countDownLatch的计数器变为0
        countDownLatch.await();
        System.out.println("3");
    }
}

结果

1
2
3

代码
1.先创建一个CountDownLatch,设置计数器为2
2.创建两个线程,调用await()方法阻塞当前线程。
3.第一个线程执行输出“1”,然后执行countDown()方法,计数器-1
4.第二个线程执行输出“2”,等待2秒,执行countDown()方法,计数器-1
5.当两秒后第二个线程执行完countDown()方法后,CountDownLatch的计数器变为0,阻塞线程将继续执行,输出“3”。

使用场景

假设两个线程,A程执行了部分逻辑后需要调用B线程,当B线程处理完后,A线程继续执行,使用CountDownLatch应该怎么实现呢?

package com.sy.thread.example;

import java.util.concurrent.CountDownLatch;

/**
 * Description: thread
 *
 * @author songyu
 */
public class CountDwonLatchTest2 {
    /**
     * 创建CountDownLatch,计数器设置为2
     */
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    static Thread A = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                System.out.println("A线程开始执行");
                System.out.println("A线程处理部分逻辑。。。。。。");
                System.out.println("让B线程开始执行");
                B.start();
                countDownLatch.await();
                System.out.println("B线程执行结束,A线程继续执行");
                System.out.println("执行结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    },"A");

    static Thread B = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("B线程开始执行");
            System.out.println("B线程执行结束,让A线程继续执行");
            countDownLatch.countDown();
        }
    },"B");

    public static void main(String[] args) {
        A.start();
    }

}

执行结果

A线程开始执行
A线程处理部分逻辑。。。。。。
让B线程开始执行
B线程开始执行
B线程执行结束,让A线程继续执行
B线程执行结束,A线程继续执行
执行结束

通过执行结果可以看出在A线程中让B线程开始执行后,调用await()方法进入阻塞,直到B线程执行结束后,调用countDown()方法后,让计数器变为0后,A线程才继续执行。

相关文章

网友评论

      本文标题:等待多线程完成 - CountDownLatch

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