• 倒计数锁存器(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方法用来知道阻塞的线程是否被中断。

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

  • 相关阅读:
    PAT 1037. 在霍格沃茨找零钱(20)
    PAT 1036. 跟奥巴马一起编程(15)
    Topcoder SRM633 DIV2 解题报告
    HDU 4565 So Easy! 矩阵快速幂 + 共轭数
    HDU 2256 Problem of Precision 矩阵快速幂 + 共轭数
    FZU 1683 纪念SlingShot 矩阵快速幂
    CodeForces 185A Plant 矩阵快速幂
    HDU 2604 Queuing 矩阵快速幂
    HDU 1575 Tr A 矩阵快速幂
    HDU 1757 A Simple Math Problem 矩阵快速幂
  • 原文地址:https://www.cnblogs.com/ylsforever/p/8434863.html
Copyright © 2020-2023  润新知