1、简述
在并发编程中,有时我们需要协调多个线程的执行,确保它们在特定的时刻同步完成。CountDownLatch是Java并发包中提供的一种强大的工具,用于实现这种同步。本文将深入探讨CountDownLatch的基本原理,以及一些实际应用场景中的巧妙应用。
2、基本原理
CountDownLatch内部维护一个计数器,初始化时设定一个值,该值表示需要等待完成的线程数。每个线程完成自己的任务后,将计数器减一,直到计数器为零。等待的线程通过await方法阻塞,直到计数器为零,然后继续执行。
3、应用场景
3.1 并发任务等待
假设有一个任务需要等待多个子任务完成后才能执行,可以使用CountDownLatch来实现等待机制。
public class ConcurrentTask {
private static final int THREAD_COUNT = 5;
private static CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < THREAD_COUNT; i++) {
new Thread(() -> {
// 子任务的业务逻辑
System.out.println(Thread.currentThread().getName() + " is working.");
latch.countDown(); // 子任务完成,计数器减一
}).start();
}
latch.await(); // 等待所有子任务完成
System.out.println("All tasks have been completed. Main task can proceed.");
}
}
3.2 控制并发线程数量
在某些场景下,需要控制同时执行的线程数量,可以使用CountDownLatch来控制。
public class ConcurrentControl {
private static final int MAX_CONCURRENT_THREADS = 3;
private static CountDownLatch latch = new CountDownLatch(MAX_CONCURRENT_THREADS);
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(MAX_CONCURRENT_THREADS);
for (int i = 0; i < 10; i++) {
executorService.submit(() -> {
try {
// 并发执行的业务逻辑
System.out.println(Thread.currentThread().getName() + " is working.");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown(); // 线程完成,计数器减一
}
});
if ((i + 1) % MAX_CONCURRENT_THREADS == 0) {
latch.await(); // 等待当前批次的线程完成
System.out.println("Batch of threads have been completed.");
latch = new CountDownLatch(MAX_CONCURRENT_THREADS); // 重置计数器
}
}
executorService.shutdown();
}
}
4、结论
CountDownLatch是一个在并发编程中非常实用的工具,通过它我们可以轻松实现多个线程之间的同步。在实际应用中,可以根据不同场景灵活运用,用于任务等待、并发线程数量控制等情况。然而,在使用过程中需要注意计数器的递减和重置,以确保线程同步的正确性。通过巧妙应用CountDownLatch,可以使得并发编程更加简单、清晰、可控。