zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    ios app: 使用企业license设置发布app的过程
    gtest测试代码编写思想
    受尽侮辱的语言
    创业者的思维误区---《精益创业》
    session的取代者:Json Web Tokens----在客户端存储登陆状态
    lineman 的理念与 modern web app
    angularjs框架及其生态环境 --待续
    javascript的崛起及其生态元素
    Cassandra 2.x 提示“错误: 代理抛出异常错误: java.lang.NullPointerException”
    cassandra运行出现了Unable to gossip with any seeds,cqlsh链接不上,提示connection refused处理办法
  • 原文地址:https://www.cnblogs.com/fruitknife/p/9703140.html
Copyright © 2011-2022 走看看