CountDownLatch
是一个同步辅助类,可以完成类似于阻塞当前线程的功能,一个线程或多个线程一直等待,知道其他线程操作的完成。
用一个给定的计数器进行初始化,计数器的操作时原子操作.
调用await()
方法的线程会进入阻塞
状态,知道其他线程调用countDown()
使得计数器的值变成0
使用场景:
在某些业务场景中,程序执行需要等待某个条件完成后才能继续执行后续的操作,比如并行计算
package io.haitaoc.concurrency.example.aqs;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchExample1 {
private final static int threadCount = 200;
public static void main(String[] args) throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
final CountDownLatch countDownLatch = new CountDownLatch(threadCount);
for (int i = 0; i <threadCount ; i++) {
final int threadNum = i;
exec.execute(()->{
try {
test(threadNum);
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
countDownLatch.countDown();
}
});
}
countDownLatch.await(); // 确保上述过程执行完才执行后续语句
System.out.println("finish");
exec.shutdown();
}
private static void test(int threadNum) throws InterruptedException {
System.out.println(threadNum);
Thread.sleep(100);
}
}
指定运行时间后执行后续语句
package io.haitaoc.concurrency.example.aqs;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class CountDownLatchExample2 {
private final static int threadCount = 200;
public static void main(String[] args) throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
final CountDownLatch countDownLatch = new CountDownLatch(threadCount);
for (int i = 0; i <threadCount ; i++) {
final int threadNum = i;
exec.execute(()->{
try {
test(threadNum);
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
countDownLatch.countDown();
}
});
}
// 10毫秒结束,200个线程没调用完就输出finish
countDownLatch.await(10,TimeUnit.MILLISECONDS); // 确保上述过程执行完才执行后续语句
System.out.println("finish");
exec.shutdown();
}
private static void test(int threadNum) throws InterruptedException {
Thread.sleep(100);
System.out.println(threadNum);
}
}