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方法用来知道阻塞的线程是否被中断。

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

  • 相关阅读:
    开始学习Angular Mobile UI
    .Net程序员飞扬有用的85个工具
    数据库查询效率,百万数据测试
    SQL Join的一些总结
    MODRD 指令 读取地址是哪儿来的
    如何在不同编程语言中获取现在的Unix时间戳(Unix timestamp)?
    easyui datagrid 的分页刷新按钮
    HttpRequest Get Post,WebClient Get
    GetWindowThreadProcessId用法(转)
    EASYUI DATAGRID 多列复选框CheckBox
  • 原文地址:https://www.cnblogs.com/ylsforever/p/8434863.html
Copyright © 2011-2022 走看看