package com.mmall.concurrency.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Slf4j
public class CountDownLatchExample2 {
private final static int threadCount = 200;
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool();
final CountDownLatch countDownLatch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
final int threadNum = i;
// Thread.sleep(100); // 不能放在这里,必须要在线程池包围内才有效
exec.execute(() -> {
try {
test(threadNum);
} catch (Exception e) {
log.error("exception", e);
} finally {
countDownLatch.countDown();
}
});
}
countDownLatch.await(10, TimeUnit.MILLISECONDS);
log.info("finish");
exec.shutdown();
}
private static void test(int threadNum) throws Exception {
Thread.sleep(100);
log.info("{}", threadNum);
}
}
分析
- countDown(计数器减1),当计数器为 0 时,则执行 await 方法后的逻辑,可以指定等待时间,比如十秒,如果超过十秒,不管countDown计数器是否为0,都会执行await后面的逻辑。
- await 这里的等待时间,表示的是逻辑执行的时间,所以不能把 sleep 放在线程池循环之外。
- exec.shutdown之后,线程并不会立马关闭,而是会等待当前任务执行完毕后才关闭。