最佳答案CountDownLatch - 倒计时门闩什么是CountDownLatch: CountDownLatch(倒计时门闩)是Java并发包中的一个实用类,用于同步多线程操作。它允许一个或多个线程等待其他线程完成操作后...
CountDownLatch - 倒计时门闩
什么是CountDownLatch:
CountDownLatch(倒计时门闩)是Java并发包中的一个实用类,用于同步多线程操作。它允许一个或多个线程等待其他线程完成操作后再进行下一步的操作。当某个操作被延迟直至其他线程完成时,可以使用CountDownLatch来实现线程之间的等待。
CountDownLatch的工作原理:
CountDownLatch内部维护了一个计数器,当创建CountDownLatch对象时,需要参数指定计数器的初始值。当调用CountDownLatch的countDown()
方法时,计数器的值减1;当计数器的值减为0时,所有等待线程都会被唤醒,可以继续执行。
CountDownLatch的常见应用场景:
1. 等待多个线程完成:
CountDownLatch可以用来等待多个线程的执行结果。例如,如果有一个任务需要等待所有子任务都完成后才能执行,可以使用CountDownLatch实现这个等待过程。
CountDownLatch latch = new CountDownLatch(3);
public class Worker implements Runnable { private CountDownLatch latch; public Worker(CountDownLatch latch) { this.latch = latch; } public void run() { // 执行任务 // ... // 完成任务后调用countDown() latch.countDown(); }}public class Master implements Runnable { private CountDownLatch latch; public Master(CountDownLatch latch) { this.latch = latch; } public void run() { try { // 等待所有任务完成 latch.await(); // 所有子任务完成后执行主任务 // ... } catch (InterruptedException e) { e.printStackTrace(); } }}public class Main { public static void main(String[] args) { int nWorkers = 3; CountDownLatch latch = new CountDownLatch(nWorkers); ExecutorService executorService = Executors.newFixedThreadPool(nWorkers); // 创建并提交子任务 for (int i = 0; i < nWorkers; i++) { executorService.execute(new Worker(latch)); } executorService.shutdown(); // 创建并启动主任务 new Thread(new Master(latch)).start(); }}
在上述示例中,创建了一个CountDownLatch对象,并通过latch.await()
在主任务中等待所有子任务完成。每个子任务完成后通过latch.countDown()
调用进行计数,直到计数器值为0时,主任务继续执行。
2. 等待某个条件满足:
CountDownLatch也可以用于等待某个条件满足后,再进行后续操作。例如,在某个多线程应用中,需要等待一组线程完成某个操作后才能继续执行,可以使用CountDownLatch来实现这个等待过程。
CountDownLatch latch = new CountDownLatch(1);
public class Validator implements Runnable { private CountDownLatch latch; public Validator(CountDownLatch latch) { this.latch = latch; } public void run() { // 等待条件满足 // ... // 条件满足后调用countDown() latch.countDown(); }}public class Main { public static void main(String[] args) { CountDownLatch latch = new CountDownLatch(1); ExecutorService executorService = Executors.newFixedThreadPool(1); // 提交任务 executorService.execute(new Validator(latch)); executorService.shutdown(); try { // 等待条件满足 latch.await(); // 条件满足后执行后续操作 // ... } catch (InterruptedException e) { e.printStackTrace(); } }}
在上述示例中,创建了一个CountDownLatch对象,并通过latch.await()
在主任务中等待条件满足。在某个线程满足条件后通过latch.countDown()
调用进行计数,主任务继续执行。
3. 控制并发任务的执行流程:
CountDownLatch可以用于控制并发任务的执行流程。例如,某个任务需要等待多个并发任务都完成后才能继续执行,可以使用CountDownLatch来实现这个控制过程。
CountDownLatch latch = new CountDownLatch(n);
public class Worker implements Runnable { private CountDownLatch latch; private int workerNum; public Worker(CountDownLatch latch, int workerNum) { this.latch = latch; this.workerNum = workerNum; } public void run() { // 执行并发任务 // ... // 完成并发任务后调用countDown() System.out.println(\"Worker \" + workerNum + \" completed.\"); latch.countDown(); }}public class Main { public static void main(String[] args) { int nWorkers = 5; CountDownLatch latch = new CountDownLatch(nWorkers); ExecutorService executorService = Executors.newFixedThreadPool(nWorkers); // 创建并提交并发任务 for (int i = 0; i < nWorkers; i++) { executorService.execute(new Worker(latch, i)); } executorService.shutdown(); try { // 等待所有并发任务完成 latch.await(); // 所有并发任务完成后执行后续操作 // ... } catch (InterruptedException e) { e.printStackTrace(); } }}
在上述示例中,创建了一个CountDownLatch对象,并通过latch.await()
在主任务中等待所有并发任务完成。每个并发任务完成后通过latch.countDown()
调用进行计数,直到计数器值为0时,主任务继续执行。
总结:
CountDownLatch是Java并发包中非常实用的一个类,它可以帮助我们控制多线程操作的同步和等待过程。通过使用CountDownLatch,我们可以实现多个线程之间的协同工作,以及对线程的调度和控制。在并发编程中,合理运用CountDownLatch可以提高代码的可靠性和效率。