CountDownLatch应用场景实践

一.CountDownLatch介绍

        CountDownLatch是一个并发工具类, 作用是允许一个或多个线程等待其他线程完成操作。我们有时会称之为发令枪。有一个个形象的例子能说明其功能:公司召开一个全体股东会,需要所有股东到场了才能正式开始。会议室准备了一个花名册,记录了需要到会的总人数,每一个股东来到会议室就要签名确认,同时总人数减一,当需要到会的总人数为0时,会议就正式开始。所以,CountDownLatch就有充当计数器和发令枪的功能。

二.结合ExecutorService实现拆分任务并发执行

       一般我们业务场景中经常会有执行一个大任务,如果我们串行执行,则效率较慢。我们应用分而治之的思想,将其拆分,启动多个线程来并行。但是如果目前不阻塞主线程,可能在子线程进行中的过程中,主线程已结束。这样也无法最终汇总结果了。此时引入CountDownLatch便能解决这个痛点。

//利用countDownLatch结合ExecutorService在并发执行任务时,能够保证子线程任务结束后,主线程才继续往下走。
		CountDownLatch countDownLatch = new CountDownLatch(3);
		ExecutorService executorService = Executors.newFixedThreadPool(3);
		Runnable runnable1 = () -> {
			System.out.println(111111);
			countDownLatch.countDown();
		};
		Runnable runnable2 = () -> {
			System.out.println(222222);
			countDownLatch.countDown();
		};
		Runnable runnable3 = () -> {
			System.out.println(333333);
			countDownLatch.countDown();
		};
		executorService.execute(runnable1);
		executorService.execute(runnable2);
		executorService.execute(runnable3);
		//阻塞当前主线程
		countDownLatch.await();
		System.out.println("主线程结束返回结果");

任务拆分为几个线程来执行,则CountDownLatch就是多少。

当子线程都执行完毕了,此时CountDownLatch为0,主线程不再阻塞,继续往下走。

三.模拟高并发

有时我们写测试用例时,想要模拟一些并发场景,这时可以引入CountDownLatch。

private static final int MAX_THREAD = 10000;
private CountDownLatch cdl = new CountDownLatch(MAX_THREAD);

@Test
public void countDownLatchTest() throws InterruptedException {
		//模拟并发
		for (int i =0;i {
				cdl.countDown();
				try {
					cdl.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				//测试调用业务接口等
				System.out.println(new Date());
			});
			thread.start();
		}
		Thread.sleep(2000);
	}

如上便是模拟10000的并发,主线程肯定要sleep下,不然直接就结束了,子线程的结果也会来不及打印出来。

你可能感兴趣的:(java)