CountDownLatch使用

CountDownLatch作用阻塞一个或多个线程等待其他线程完成操作。

定义初始化的时候,需要传入一个正数来初始化计数器(0也可以,但这样定义没有实际意义)。有两个方法countDown()用于递减计数器,await()方法阻塞当前线程,直到计数器递减为0

CountDownLatch通常用于多个线程之间的协调工作。

假设有如下情节:

同时获取5张表的数据并一同返回

为了让cpu更好的得到利用,程序执行效率更高,使用多线程来完成。

public class CountDownLatchExample {
    // 循环次数
   private static final int FOR_NUMBER = 5;


    public static void main(String[] args) {

        // 查询数据
        for (int i = 0; i < FOR_NUMBER; i++) {
            new Thread(() -> {
                System.out.println("查询第:\t" + Thread.currentThread().getName() + "张表数据完成!");
            }, String.valueOf(i)).start();
        }


        System.out.println("查询完毕");

    }
}

我们看一下执行结果是否是我们想要的结果。

image-20200105175835144

可以看到,还有数据没查询完成他就体检进行查询完毕的操作了。那如果在实际开发过程中,就等于数据还没处理完成就返回用户数据了。这并不是我们想要的结果。

那么刚才也有说CountDownLatch是阻塞一个或多个线程等待其他线程完成操作,那么我们试一下。

public class CountDownLatchExample {
    // 循环五次
   private static final int FOR_NUMBER = 5;

   // 实例化定义一个CountDownLatch需要减少的总次数
   private static CountDownLatch countDownLatch = new CountDownLatch(5);


    public static void main(String[] args) {

        // 查询数据
        for (int i = 0; i < FOR_NUMBER; i++) {
            new Thread(() -> {
                System.out.println("查询第:\t" + Thread.currentThread().getName() + "张表数据完成!");

                // 执行完 查询 然后进行递减操作 每次减1
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        }

        try {
            countDownLatch.await(); // await()方法起到阻塞的作用,直到计数器值等于0
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        System.out.println("查询完毕");

    }
}

上边我们定义了一个CountDownLatch里边值写入的是5表明我们总共需要减少的次数,再每次执行完查询操作完成后进行减1操作,最后在执行完毕之前进行await()方法阻塞,计数器为0则才放过往下走。我们看一下就结果是否跟想象的一样。

image-20200105180700120

OKK!非常完美的达到了预期的效果。

总体CountDownLatch的作用以及使用就没有了,很简单,大家可以多多尝试。在开发中用到非常多。

补充:

CountDownLatchawait()有重载方法await(long timeout, TimeUnit unit), timeout则是设置最大等待时间,unit则是时间类型,如果超过这个时间程序则将继续执行,不再阻塞。

你可能感兴趣的:(CountDownLatch使用)