Java并发基础 - CountDownLatch&CyclicBarrier

构造器中传入的countint类型,这个计数器的初始值就是需要等待的线程数量。这个值只能被设置一次,并且CountDownLatch不提供任何方法去修改或重置这个值。

countDown方法:

countDownLatch.countDown();

复制代码

每当一个线程完成了自己的任务后,调用该方法,计数器的值减1。当计数器的值为0时,表示所有线程都已经完成了任务,然后在锁上等待的线程就可以恢复执行任务。

await方法:

countDownLatch.await();

复制代码

一般主线程在启动其他线程后调用该方法,这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务。一般而言,与CountDownLatch的第一次交互就是在这里,主线程等待其他线程。

下面以一个例子来看一下具体的使用:假设我们通过第三方机构查询机票,第三方会分别去统计各个航空公司的现存票数,查询全部完成后再返回结果。主线程:

public class CountDownDemo {

private static List company= Arrays.asList(“山航”,“东航”,“青航”);

private static List flightList=new ArrayList<>();

public static void main(String[] args) throws InterruptedException {

CountDownLatch countDownLatch=new CountDownLatch(company.size());

for (int i = 0; i < company.size(); i++) {

String name=company.get(i);

QueryThread queryThread=new QueryThread(countDownLatch,flightList,name);

new Thread(queryThread).start();

}

countDownLatch.await();

System.out.println(“=查询结束=”);

flightList.forEach(System.out::println);

}

}

复制代码

查询线程:

public class QueryThread implements Runnable{

private CountDownLatch countDownLatch;

private List fightList=new ArrayList<>();

private String name;

public QueryThread(CountDownLatch countDownLatch,List fightList, String name) {

this.countDownLatch = countDownLatch;

this.fightList=fightList;

this.name = name;

}

@Override

public void run() {

int val=new Random().nextInt(10);

try {

System.out.printf(“%s开始查询!\n”,name);

TimeUnit.SECONDS.sleep(val);

fightList.add(name+“票数:”+val);

System.out.printf(“%s查询成功!\n”,name);

countDownLatch.countDown();

}catch (Exception e){

e.printStackTrace();

}

}

}

复制代码

执行代码:

图片

从执行结果可以看出,在3个查询线程均完成查询后,唤醒主线程,返回了最终数据。

通过这个例子,我们可以得出,如果一个接口依赖了多个第三方服务或外部接口,那么如果串行调用的话执行时间必然很长,这时候就可以使用CountDownLatch进行并行调用,这一点的思路也比较像使用消息队列对上下游系统进行解耦的过程。

CyclicBarrier


CyclicBarrier可以被翻译为“循环栅栏”,通过它可以实现让一组线程等待至某个状态之后再同步执行。“循环”这一点体现在当所有的等待线程都被释放后,CyclicBarrier可以被重用。

执行的基本原理是,当线程调用了CyclicBarrierawait()方法后,就会处于一个barrier的状态,也就是遇到了一个屏障。如果所有线程都执行到这个状态,那么这个屏障就会打开,使所有线程继续向下执行。

先看一下常用的几个重要方法,首先看构造方法:

CyclicBarrier barrier=new CyclicBarrier(parties);

复制代码

这里的parties就是参与线程的个数。

await()方法:

barrier.await();

复制代码

线程调用该方法表示自己已经到达栅栏。

以5名选手进行赛跑为例,这个过程必须要等到所有运动员到达起跑线才开始正式比赛,正好符合CyclicBarrier的思想。

public class CyclicBarrierDemo {

总结

如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了

《Java中高级核心知识全面解析》

小米商场项目实战,别再担心面试没有实战项目:

如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了

《Java中高级核心知识全面解析》

[外链图片转存中…(img-9gqhM02N-1721140599744)]

小米商场项目实战,别再担心面试没有实战项目:

[外链图片转存中…(img-WibuHCbS-1721140599745)]

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值