CountDownLatch

CountDownLatch


CountDownLatch与CyclicBarrier有点儿相似。

CyclicBarrier所描述的是“允许一组线程互相等待,直到到达某个公共屏障点,才会进行后续任务”,而CountDownLatch所描述的是”在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待“。在API中是这样描述的:

用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。

其内部实现使用了队列同步器:

private static final class Sync extends AbstractQueuedSynchronizer

构造方法

//有一个参数,计数器,表示线程的数量
public CountDownLatch(int count) {
    if (count < 0) throw new IllegalArgumentException("count < 0");
    this.sync = new Sync(count);
}

公共方法

//在计数器变为0或者该线程被中断之前一直保持等待
public void await() throws InterruptedException {
    sync.acquireSharedInterruptibly(1);
}
//加了等待时间
public boolean await(long timeout, TimeUnit unit)
    throws InterruptedException {
    return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
//count减一
public void countDown() {
    sync.releaseShared(1);
}
//返回当前的count值
public long getCount() {
    return sync.getCount();
}

使用实例

还是四个人相约玩游戏,游戏大厅和飞机等待玩家准备,四人都准备了,游戏才开始。

package my.syn;

import java.util.concurrent.CountDownLatch;

import static my.syn.MyGame.countDownLatch;

/**
 * @ClassName: MyGame
 * @author: Yang.X.P
 * @date: 2018-09-17 16:24
 **/
public class MyGame implements Runnable{
    static CountDownLatch countDownLatch = new CountDownLatch(4);
    @Override
    public void run() {
        System.out.println("游戏大厅已加载好,等待所有玩家准备好,即可进入");
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("所有人到准备好了,游戏开始...");
    }
    public static void main(String[] args){
        Player player = new Player();
        MyGame myGame = new MyGame();
        Aircraft aircraft = new Aircraft();
        Thread airThread = new Thread(aircraft);
        Thread gameThread = new Thread(myGame);
        gameThread.start();
        airThread.start();
        for (int i = 0; i < 4; i++) {
            Thread playerThread = new Thread(player);
            playerThread.start();
        }
    }
}
class Aircraft implements Runnable {

    @Override
    public void run() {
        System.out.println("飞机准备好了,等待起飞");
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("玩家到齐,飞机起飞!");
    }
}
class Player implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "准备好了");
        countDownLatch.countDown();
    }
}

参考资料:

http://cmsblogs.com/?p=2253

posted @ 2018-09-25 20:08  一把水果刀  阅读(161)  评论(0编辑  收藏  举报