CountDownLatchCyclicBarrierSemaphore多线程协助操作API
Posted learning_code_blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CountDownLatchCyclicBarrierSemaphore多线程协助操作API相关的知识,希望对你有一定的参考价值。
目录
主要说一下应用场景
Semaphore信号量
场景:Semaphore 许可证
1、可以限制每个资源同时处理能力 比如:一个API接口、限制只能同时两个线程响应请求,其余的线程需要等待
处理逻辑:
a.获取线程之后semaphore.acquire() -- 如果没有获取,则会阻塞
b.用完之后释放 semaphore.release();
场景1:一个API接口,限制同时只能两个线程想相应请求,针对单机版本,可以做限流处理。
public class SemaphoreDemo01
static Semaphore semaphore = new Semaphore(3);
/**
* Semaphore 许可证
* 1、可以限制每个资源同时处理能力 比如:一个API接口、限制只能同时两个线程响应请求,其余的线程需要等待
* 处理逻辑:
* a.获取线程之后semaphore.acquire() -- 如果没有获取,则会阻塞
* b.用完之后释放 semaphore.release();
* @param args
*/
public static void main(String[] args)
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++)
int finalInt = i ;
executorService.submit(() ->
try
// 获取许可证 如果没有获取,则会阻塞
semaphore.acquire();
// semaphore.acquire(2); // 可以一次性获取2个授权
catch (InterruptedException e)
e.printStackTrace();
System.out.println(Thread.currentThread().getName()+"拿到许可证,耗时2 s");
try
Thread.sleep(2000);
catch (InterruptedException e)
e.printStackTrace();
System.out.println("慢服务执行完成:"+Thread.currentThread().getName());
// 释放许可证
semaphore.release();
);
executorService.shutdown();
CountDownLatch协助线程
两种用法:允许一个或多个线程,等待其他一组线程完成操作,再继续执行。
场景1:eg: 比如去查询外部接口API,多个不同类型的API都需要请求
跑步为例,所有runner都需要等待裁判员枪响之后才开始运动
public class CountDownLatchDemo03
/**
* 运动员 到达终点、所有场景统一汇合之后然后进行
*/
static CountDownLatch countDownLatch = new CountDownLatch(10);
public static void main(String[] args) throws InterruptedException
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++)
int finalInt = i ;
executorService.submit(()->
try
Thread.sleep((long) (Math.random()*100));
countDownLatch.countDown();
catch (Exception e)
e.printStackTrace();
System.out.println("第" + finalInt + "号 到达终点 ");
);
System.out.println("等待所有运动员跑完");
countDownLatch.await();
System.out.println("所有人都跑完了");
executorService.shutdown();
场景2
- 运动员到达终点时,需要知道是否已经所有运动员已经到场了
- 程序中,比如买机票,针对同一个行程,从不同的航空公司获取对应的票价返回给前端。
public class CountDownLatchDemo03
/**
* 运动员 到达终点
*/
static CountDownLatch countDownLatch = new CountDownLatch(10);
public static void main(String[] args) throws InterruptedException
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++)
int finalInt = i ;
executorService.submit(()->
try
Thread.sleep((long) (Math.random()*100));
countDownLatch.countDown();
catch (Exception e)
e.printStackTrace();
System.out.println("第" + finalInt + "号 到达终点 ");
);
System.out.println("等待所有运动员跑完");
countDownLatch.await();
System.out.println("所有人都跑完了");
executorService.shutdown();
CyclicBarrier 循环利用
场景: 多人骑行车、多人坐船
eg:
比如去海边游玩,三人自行车、需要等待三人才能开始,下大巴车之后到海边有一段距离(需要步行,每个人的速度不一样),所以就出现了必须要三个人之后才能启动自行车
public class CyclicBarrierDemo01
// 参数构建 还可以添加其他的
// 方式1// private static CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
// 方式2 循环一次(在开闸的时候) 打印一次
private static CyclicBarrier cyclicBarrier = new CyclicBarrier(4,()->
System.out.println("凑够人数了。 出发!");
);
public static void main(String[] args)
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 16; i++)
int finalInt = i ;
System.out.println("第" + finalInt +" 前往,等待启动");
executorService.submit(()->
try
Thread.sleep((long) (Math.random()*1000));
catch (InterruptedException e)
e.printStackTrace();
System.out.println("第" + finalInt +" 到达驿站,等待启动");
try
cyclicBarrier.await(10, TimeUnit.SECONDS);// 当不足时,超过时间区间。则会抛出异常
System.out.println("第" + finalInt +" 开始骑车");
catch (InterruptedException e)
e.printStackTrace();
catch (BrokenBarrierException e)
e.printStackTrace();
catch (TimeoutException e)
e.printStackTrace();
);
executorService.shutdown();
总结
# Semaphore 信号量
1、控制用户请求的数量。比如限制2个线程进入,其余的线程则需要等待,直到某个线程完成才会重新进入新的线程工作
# CountDownLatch
用法1:
主线程等待-多个子线程执行完成之后一起执行
eg: 比如去查询外部接口API,多个不同类型的API都需要请求,
**1.api1 2.api2 3.api3**
一般做法: 一次调用api1、api2、api3
同时调用 :多线程调用api1、api2、api3
最后主线程等待即可
用法2:
多个线程等待某一个线程信号,同时开始执行
eg: 同时5个线程同时争夺某个资源
一般在测试类中使用
# CyclicBarrier 循环使用场景
场景:
比如 划船,必须4个人一组,否则不允许开船,并且可以循环执行
代码连接地址 demo链接
以上是关于CountDownLatchCyclicBarrierSemaphore多线程协助操作API的主要内容,如果未能解决你的问题,请参考以下文章