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

2022-06-17 09:55:31

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

CountdownLatch基本介绍

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

场景介绍

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

代码实现

publicclassCountDownLatchService{protectedActor actor;protectedCourse course;protectedCountDownLatchService(Actor actor,Course course){this.actor= actor;this.course= course;}privatestaticfinalint threadSize=5;privateboolean isRunning=false;privatestaticfinalCountDownLatch latch=newCountDownLatch(2);privatestaticfinalThreadPoolExecutor executor=newThreadPoolExecutor(
			threadSize+1,
			threadSize+1,10,TimeUnit.SECONDS,newSynchronousQueue<>());publicintinit(){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=false
				isRunning=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("信息返回结束");return0;}publicstaticvoidmain(String[] args){Actor actor=newActor();Course course=newCourse();CountDownLatchService countDownLatchService=newCountDownLatchService(actor, course);
		countDownLatchService.init();}}

需要注意的点

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

  • 作者:咖啡不苦**
  • 原文链接:https://blog.csdn.net/huo065000/article/details/122879971
    更新时间:2022-06-17 09:55:31