前言: 一个使用场景,例如分发10个线程,需要等到这10个线程全部都执行完毕后,再进行下一步的处理。
看到过一个例子:举行跑步比赛,发令枪响后,几位选手开始跑步,当最后一位选手跑完全程,然后开始公布选手成绩、以及颁奖仪式。
- 模拟多个线程同时执行的场景
- 模拟依赖场景,例如一个数据的计算需要很多数据来源,需要这些数据来源全部加载完毕后才开始进行计算。
主要方法
int getCount
await()
public class LatchTest {
private static final Logger LOGGER = Logger.getLogger("LatchTest");
@Test
public void test() {
CountDownLatch latch = new CountDownLatch(1);
for (int i = 0; i < 10; i++) {
new Thread(deal(i, latch)).start();
}
LOGGER.info("3秒后开始....");
SleepUtil.sleep(3000);
latch.countDown();
}
private Runnable deal(int threadNum, CountDownLatch latch) {
return new Runnable() {
@Override
public void run() {
try {
latch.await();
LOGGER.info("开始运行...");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
}
@Test
public void test2() {
CountDownLatch latch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
new Thread(deal2(i, latch)).start();
}
LOGGER.info("等待加载中...");
try {
latch.await();
LOGGER.info("开始进入主界面");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
private Runnable deal2(int threadNum, CountDownLatch latch) {
return new Runnable() {
@Override
public void run() {
try {
LOGGER.info(threadNum + "开始运行");
SleepUtil.sleep(1000);
LOGGER.info(threadNum + "运行结束");
} catch (Exception e) {
} finally {
latch.countDown(); // 放在finally语句块中,无论程序正常执行还是出现异常,都会执行
}
}
};
}
}