乐趣区

计数器CountDownLatchCountDownLatchCyclicBarrier

//    创建 2 个线程的线程池 
Executor executor =    Executors.newFixedThreadPool(2);
while(存在未对账订单){        
    //    计数器初始化为 2        
    CountDownLatch latch = new CountDownLatch(2);        
    //    查询未对账订单        
    executor.execute(()->{pos = getPOrders();                
        latch.countDown();});        
    //    查询派送单        
    executor.execute(()->{dos = getDOrders();                
        latch.countDown();});                
    //    等待两个查询操作结束        
    latch.await();                
    //    执⾏对账操作        
    diff = check(pos, dos);        
    //    差异写⼊差异库        
    save(diff); 
}

计数器

CountDownLatch:一个线程等待多个线程。

// 定义一个初始值为 2 的计数器
CountDownLatch latch = new CountDownLatch(2);
// 计数器 -1
latch.countDown();
// 线程等待,等待至计数结束。latch.await();

CyclicBarrier:多个线程相互等待,等待结束执行回调。

// 创建一个初始值为 2 得计数器    
CyclicBarrier barrier =     new CyclicBarrier(2, 
                    ()->{ executor.execute(()->check()); // 回调函数                                                   
});    
// 等待
barrier.await();
  • 调用 await() 计数器减 1,同时等待计数器变为 0。
  • 当计数器减到 0 时持有 barrier.await() 的线程会向下执行,同时调用 barrier 的回调函数。
  • 可以循环利用,具备自动重置功能。

总结:

CountDownLatch 主要用来解决一个线程等待多个线程的场景 ,可以类比旅游团团长要等待所有的游客到齐才能去下一个景点;而 CyclicBarrier 是一组线程之间互相等待 ,更像 是几个驴友之间不离不弃。除此之外 CountDownLatch 的计数器是不能循环利用的 ,也就是说一旦计数器减到 0,再有线程调用 await(),该线程会直接通过。但 CyclicBarrier 的计数器是可以循环利用的,而且具备自动重置的功能 ,一旦计数器减到 0 会自动重置到你设置的初始值。除此之外,CyclicBarrier 还可以设置回调函数。


码字不易如果对你有帮助请给个关注

爱技术爱生活 QQ 群: 894109590

退出移动版