CountDownLatch 概述
CountDownLatch 是并发编程中提供的一个工具类,里面封装着一个线程倒数计数器。有点类似运动会上的发令枪。倒数到 0 就开始发令赛跑。
下面开始利用该工具类模拟一个并发场景,代码如下:
public class CoundDownLatchTest {
public static int COUNT = 0;
public static final int THREAD_COUNT = 100;
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(THREAD_COUNT);
for (int i = 0; i < THREAD_COUNT; i++) {
new Thread(()->{
// 这里是发令枪,有 100 个线程在这里等着起跑
countDownLatch.await();
TimeUnit.MILLISECONDS.sleep(100);
CoundDownLatchTest.COUNT++;
}).start();
countDownLatch.countDown();
}
TimeUnit.MILLISECONDS.sleep(500);
System.out.println("CarBuilderTest.COUNT = " + CoundDownLatchTest.COUNT);
}
}
上述通过 CountDownLatch 工具类的 API countDownLatch.await()
让 100 个线程在这里等待指令。当 100 个线程都准备好了之后就开始竞争操作。这样模拟出的场景非常接近业务中高并发,平常测试时可以用用,不过更多的还是借助老朋友 JMeter 工具。
另外也可以通过 CountDownLatch 来等待所有线程执行完获取结果,代码如下:
public class CoundDownLatchTest2 {
public static int COUNT = 0;
public static final int THREAD_COUNT = 100;
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(THREAD_COUNT);
for (int i = 0; i < THREAD_COUNT; i++) {
new Thread(()->{
try {
// 这里是发令枪
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
CoundDownLatchTest2.COUNT++;
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
System.out.println("CarBuilderTest.COUNT = " + CoundDownLatchTest2.COUNT);
}
}
主线程执行到 countDownLatch.await()
会阻塞挂起,当调用 countDownLatch.countDown()
将计数器减到 0 为止,阻塞的主线程就会被唤醒继续往下执行,从而获取到所有线程执行完之后的结果。如果不用这个阻塞,也可以使用 TimeUnit.MILLISECONDS.sleep(100)
来阻塞主线程,不过时间要自己估算,非常不稳定。