zoukankan      html  css  js  c++  java
  • 倒计数锁存器(CountDown Latch)和 CyclicBarrier(同步屏障)

    倒计数锁存器(CountDown Latch)是异常性障碍,允许一个或多个线程等待一个或者多个其他线程来做某些事情。

     public  static long time(Executor executor,int concurrency,final Runnable action)throws InterruptedException{
            //CountDownLatch 构造器参数代表 只有调用countDown()方法达到这个int值的时候,才能继续(所以多线程的情况下可以在此阻塞)
            final CountDownLatch ready=new CountDownLatch(concurrency);
            final CountDownLatch start=new CountDownLatch(1);
            final CountDownLatch done=new CountDownLatch(concurrency);
            for (int i=0;i<concurrency;i++){
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        ready.countDown();//准备好了一个就++1
                        try{
                            start.await();//等待所有for循环跑完 主线程执行countDown的时候才能继续走
                            action.run();
                        }catch (InterruptedException ex){
                            Thread.currentThread().interrupt();
                        }finally{
                            done.countDown();//线程执行完了才能++
                        }
                    }
                });
            }
            ready.await();
            long startNanos=System.nanoTime();
            start.countDown();
            done.await();//阻塞等待异步线程的countDown()调用次数达到阀值
            return  System.nanoTime()-startNanos;
        }

    对于间歇式的定时,始终应该优先使用System.nanoTime()而不是System.currentTimeMills,前者更加准确更加精确并且不受系统的实时时钟的调整影响。

    三个CountdownLatch也可以用CyclicBarrier(同步屏障)代替。

     public static long time1(Executor executor, int concurrency, final Runnable action) {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(concurrency);
            long startNanos = System.nanoTime();
            for (int i = 0; i < concurrency; i++) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            action.run();
                        } finally {
                            try {
                                cyclicBarrier.await();
                            } catch (BrokenBarrierException ex) {
    
                            } catch (InterruptedException ex) {
    
                            }
                        }
                    }
                });
            }
            return System.nanoTime() - startNanos;
        }

    CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。
    CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。

    总的来说就是可以同步等待所有异步任务完成后进行汇总操作。

  • 相关阅读:
    单例模式及其调用
    SQL 语句中left join 与join 条件放置位置,进而影响SQL语句的执行效率的问题
    用辩证的方法去看待项目管理(《最后期限》、《人月神话》),没有最好的项目管理方案,只有最适合的。
    关于Aspose.Words插入表格单元格的高度问题的解决
    google guava cache
    jvm 设置
    Heron 数据模型,API和组件介绍
    基数统计的常用方法
    apache storm 1.0.0 新特性
    spark的那些坑
  • 原文地址:https://www.cnblogs.com/ylsforever/p/8434863.html
Copyright © 2011-2022 走看看