Java CountDownLatch

来源:互联网 发布:手机淘宝4.0.1 编辑:程序博客网 时间:2024/05/22 10:57

Oracle官方文档

http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html

package java.util.concurrent.CountDownLatch;

A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon – the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.

A CountDownLatch is a versatile synchronization tool and can be used for a number of purposes. A CountDownLatch initialized with a count of one serves as a simple on/off latch, or gate: all threads invoking await wait at the gate until it is opened by a thread invoking countDown(). A CountDownLatch initialized to N can be used to make one thread wait until N threads have completed some action, or some action has been completed N times.

A useful property of a CountDownLatch is that it doesn’t require that threads calling countDown wait for the count to reach zero before proceeding, it simply prevents any thread from proceeding past an await until all threads could pass.

一个同步的辅助工具类,它允许一个或多个线程等待直到一系列的操作在其它的线程中完成执行。

CountDownLatch使用给定的总数来初始化,await方法会阻塞直到由于调用了countDown方法当前的数量达到零,之后所有的等待线程都会被唤醒并且任何后续await的调用都会立即返回。该类是一次性的 —— 它的数目不能被重置。如果你需要一个可以重置总数的版本,可以考虑使用CyclicBarrier。

CountDownLatch是一个多用途的同步工具,可以被用于实现多种目的。CountDownLatch使用一个服务计数器来初始化,它就像一个简单的开关或者门:所有的线程都调用await方法在门前等待,直到门被某个调用countDown方法的线程打开。CountDownLatch使用N来初始化可以让某个线程等待其它N个线程执行完某动作,或者某个动作被执行完N次。

CountDownLatch有一个有用的属性是它不一定需要其他线程调用countDown,直到数目到达零才能继续执行,它只是简单的防止某些线程提前执行,让它们等待一会直到所有的线程都可以通过。

CountDownLatch 介绍

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。

使用场景

在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。 这个时候就可以使用CountDownLatch。CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。

代码实战

package com.demo.test;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class CountDownLatchDemo {    // 模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束    public static void main(String[] args) {        final int COUNT = 10;        final CountDownLatch beginLatch = new CountDownLatch(1);        final CountDownLatch endLatch = new CountDownLatch(COUNT);        ExecutorService executorService = Executors.newFixedThreadPool(COUNT);        for (int i = 0; i < COUNT; i++) {            final int NO = i + 1;             executorService.execute(new Runnable() {                @Override                public void run() {                    try {                        beginLatch.await();                        Thread.sleep((long) (Math.random() * 1000));                        System.out.println("No." + NO + " arrived");                      } catch (InterruptedException e) {                        e.printStackTrace();                    } finally {                        endLatch.countDown();                    }                }            });        }        System.out.println("Game Start");        //beginLatch减去1,正好为0,所有await方法返回,即比赛开始        beginLatch.countDown();        //等待endLatch变为0之后返回,即所有选手到达终点        try {            endLatch.await();        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("Game Over");    }}

运行输出

Game StartNo.3 arrivedNo.7 arrivedNo.4 arrivedNo.5 arrivedNo.2 arrivedNo.10 arrivedNo.9 arrivedNo.8 arrivedNo.6 arrivedNo.1 arrivedGame Over
0 0