欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

并发编程--CountdownLatch结合线程池实现

时间:2023-06-07

在分布式项目中,通过分布式架构实现相关功能调用,这是必然存在的。我在项目中,比如商品详情信息页面的展示,分享图的合成等场景,都会涉及到好几个分模块功能获取信息。CountdownLatch则可以很好的实现类似场景的功能实现。

CountdownLatch基本介绍

能够使一个线程等待其他线程完成各自的工作之后再执行。
详情:并发编程–CountdownLatch && CyclicBarrier

场景介绍

结合actor和course信息合成一张分享图,只介绍流程,核心代码模拟。

代码实现

public class CountDownLatchService {protected Actor actor;protected Course course;protected CountDownLatchService(Actor actor, Course course) {this.actor = actor;this.course = course;}private static final int threadSize = 5;private boolean isRunning = false;private static final CountDownLatch latch = new CountDownLatch(2);private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(threadSize + 1,threadSize + 1,10,TimeUnit.SEConDS, new SynchronousQueue<>());public int init() {if (isRunning == true) {System.out.println("线程正在运行...");return -1;}isRunning = true;executor.execute(() -> {System.out.println("获取actor相关信息");course.setName("霍霍的courseName");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}latch.countDown();System.out.println("1:"+latch.getCount());});executor.execute(() -> {System.out.println("获取course的name");actor.setName("霍霍的actorName");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}latch.countDown();System.out.println("2:"+latch.getCount());});executor.execute(() -> {System.out.println("获取course的type");//仅仅测试模拟,真实项目可能就是分布式相关任务调用course.setType(1L);try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}latch.countDown();System.out.println("3:"+latch.getCount());});executor.execute(() -> {System.out.println("等待所有信息返回=");try {System.out.println("value:"+latch.getCount());latch.await();//设置isRunning=falseisRunning = false;} catch (InterruptedException e) {e.printStackTrace();}System.out.println("course info= " + course.getName());System.out.println("actor info= " + actor.getName());//执行额外的拼接合成逻辑System.out.println("拼接图片完成");});executor.shutdown();System.out.println("信息返回结束");return 0;}public static void main(String[] args) {Actor actor = new Actor();Course course = new Course();CountDownLatchService countDownLatchService = new CountDownLatchService(actor, course);countDownLatchService.init();}}

需要注意的点

CountDownLatch初始值需谨慎考虑,比如如上demo,我需要三个获取信息的线程去执行,每次执行latch.countDown(),count就会减1.当count为0的时候,就会执行await。
想表达什么意思呢?
比如你初始值是2,执行了三个latch.countDown();
比如你初始值是4,执行了三个latch.countDown();
两个结果肯定是不同的,你去看源码就会发现,所有调用await方法的线程都会阻塞在 AQS 的阻塞队列中,通过判定count是否为0来决定是否唤起。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。