java 多线程CountDownLatch

 CountDownLatch 简介

CountDownLatch 是 Java 中的一个同步工具类,可以用来确保一组线程等待其他线程完成各自工作后再继续执行。

CountDownLatch 的应用场景

CountDownLatch 可以被广泛应用于各种多线程协作的场景,例如:

  • 主线程等待多个子线程完成后再执行下一步操作。
  • 多个子任务并行执行,最后合并结果。
  • 并行计算中,等待所有计算任务完成后进行统一汇总。

CountDownLatch 的优缺点分析
优点
简单易用:CountDownLatch 的使用非常简单,通过 await 和 countDown 方法即可实现多线程的协作。
灵活性:可以根据具体场景指定等待的计数值,可以灵活控制多个线程的协作关系。
高效性:底层使用了 AQS(AbstractQueuedSynchronizer)来实现同步,能够保证高效地协调多个线程的执行顺序。
缺点
一次性:CountDownLatch 的计数值只能减少,无法重置。一旦计数值减至零,就不能再次使用。
无法中途取消:一旦等待开始,就无法中途取消等待,除非等待超时或者发生中断。

CountDownLatch 的使用案例

 以下是一个简单的使用 CountDownLatch 的例子,假设有一个任务分配系统,其中有多个工人(线程)在处理任务,而一个管理者(主线程)需要等待所有工人完成他们的任务后才继续执行。

import java.util.concurrent.CountDownLatch;
 
public class Main {
    public static void main(String[] args) throws InterruptedException {
        int workerCount = 5; // 假设有5个工人
        CountDownLatch latch = new CountDownLatch(workerCount);
 
        for (int i = 0; i < workerCount; i++) {
            Worker worker = new Worker(latch, "Worker " + i);
            Thread thread = new Thread(worker);
            thread.start();
        }
 
        latch.await(); // 等待所有工人完成任务
        System.out.println("所有工人任务完成,管理者继续执行。");
    }
 
    static class Worker implements Runnable {
        private CountDownLatch latch;
        private String name;
 
        public Worker(CountDownLatch latch, String name) {
            this.latch = latch;
            this.name = name;
        }
 
        @Override
        public void run() {
            // 工人执行任务
            doWork();
        }
 
        private void doWork() {
            System.out.println(name + " 开始工作。");
            try {
                Thread.sleep(1000); // 模拟工作耗时
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally { 
                latch.countDown();   // 工人完成任务,计数减一 
            }
            System.out.println(name + " 工作完成。");
        }
    }
}

 注意:countDownLatch.countDown();放在finally中,防止线程异常把机器卡死。

在这个例子中,我们创建了一个 CountDownLatch 实例,其计数器初始化为工人的数量(workerCount)。每个工人线程在开始后会立即执行它的任务,任务完成后会调用 countDown 方法。主线程在开始时调用 latch.await() 方法等待计数器变为0,即所有工人完成任务。当所有工人完成任务后,计数器变为0,await 方法返回,主线程继续执行。

 

posted @ 2024-05-09 10:12  业余砖家  阅读(4)  评论(0编辑  收藏  举报