日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

并發編程CountdownLatch結合線程池實現

作者:咖啡不苦** 更新時間: 2022-06-08 編程語言

在分布式項目中,通過分布式架構實現相關功能調用,這是必然存在的。我在項目中,比如商品詳情信息頁面的展示,分享圖的合成等場景,都會涉及到好幾個分模塊功能獲取信息。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=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("信息返回結束");
		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來決定是否喚起。


原文鏈接:https://blog.csdn.net/huo065000/article/details/122879971

欄目分類
最近更新