线程间通讯

核心观点:

  • CountdownLatch阻塞主线程,等所有子线程完结了再继续下去。
  • Syslicbarrier阻塞一组线程,直至某个状态之后再全部同时执行,并且所有线程都被释放后,还能通过reset来重用。
CountDownLatchCyclicBarrier
减计数方式加计数方式
计算为0时释放所有等待的线程计数达到指定值时释放所有等待线程
计算为 0 时,无法重置计数达到指定值时,计数置为0重新开始
调用 countDown() 方法计数减一,调用 await()方法只进行阻塞,对计数没任何影响调用 await() 方法计数加 1,若加 1 后的值不等于构造方法的值,则线程阻塞
不可重复利用可重复利用

一、CountDownLatch用法

CountDownLatch类只提供了一个构造器:

public CountDownLatch(int count) {  };  //参数count为计数值

然后下面这3个方法是CountDownLatch类中最重要的方法

 //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };  

//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  

 //将count值减1
public void countDown() { }; 
  1. 可以看到子线程并没有因为调用latch.countDown而阻塞,会继续进行该做的工作,只是通知计数器-1,CountdownLatch适用于所有线程通过某一点后通知方法,
使用
  • 需要阻塞的线程调用CountDownLatch.wait(),主线程阻塞,等待计数器为0,执行逻辑
  • 子线程调用CountDownLatch.countDown() ,子线程不会被阻塞,继续执行
应用场景

开始执行前等待n 个线程完成各自任务:例如应用程序启动类要确保在处理用户请求前,所有N 个外部系统已经启动和运行了,例如处理excel 中多个表单。

二、CyclicBarrier用法

CyclicBarrier则适合让所有线程在同一点同时执行,CyclicBarrier提供2个构造器:

public CyclicBarrier(int parties, Runnable barrierAction) {
}
 
public CyclicBarrier(int parties) {
}

参数parties指让多少个线程或者任务等待至barrier状态;参数barrierAction为当这些线程都达到barrier状态时会执行的内容。

CyclicBarrier中最重要的方法就是await方法

//挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务;
public int await() throws InterruptedException, BrokenBarrierException { };

//让这些线程等待至一定的时间,
//如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { };
使用
  • 子线程调用cyclicBarrier.await(); 调用await的线程会被阻塞,等待计数器满后继续执行
  • 当计数器满后:自动调用构造器里面的 Runnable (执行其逻辑),后释放阻塞的子线程
应用场景

CyclicBarrier 可以用于多线程计算数据,最后合并计算结果的场景。,比如有3个线程Ta、Tb、Tc在执行某业务逻辑,只有当3个线程都到达屏障时,才开始执行后续的逻辑。

总结

  • CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行;
  • CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。

CountDownLatch是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而CyclicBarrier更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行。

代码练习1
练习2
练习3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值