线程同步CountDownLatch的使用

CountDownLatch 是 Java 中一个常用的同步工具类,主要用于协调多个线程的执行。它可以让一个或多个线程等待,直到其他线程执行完毕后才能继续。常见的使用场景是多个线程执行一些并行任务,主线程需要等待所有线程完成任务才能继续执行。

基本概念:

CountDownLatch 类接受一个初始计数值,这个计数值通常是线程的数量。每个线程在完成其任务时调用 countDown() 方法将计数值减 1,直到计数值为 0 时,所有调用 await() 方法的线程才会被唤醒。

主要方法:

await():当前线程阻塞,直到计数值为 0。
countDown():将计数值减 1。
getCount():返回当前计数值。

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {

    public static void main(String[] args) throws InterruptedException {
        // 假设有 3 个线程需要等待主线程
        CountDownLatch latch = new CountDownLatch(3);

        // 创建并启动 3 个线程
        for (int i = 0; i < 3; i++) {
            new Thread(new Worker(latch)).start();
        }

        // 主线程等待计数为 0
        System.out.println("Main thread is waiting for worker threads to finish.");
        //超时强制执行下面代码
  		boolean finishedOnTime = latch.await(2, TimeUnit.SECONDS);
        if (finishedOnTime) {
            System.out.println("All worker threads finished on time.");
        } else {
            System.out.println("Timeout occurred before all worker threads finished.");
        }
        System.out.println("Main thread is continuing after all worker threads are done.");
    }
}

class Worker implements Runnable {
    private final CountDownLatch latch;

    public Worker(CountDownLatch latch) {
        this.latch = latch;
    }

    @Override
    public void run() {
        try {
            // 模拟每个工作线程的任务
            System.out.println(Thread.currentThread().getName() + " is working.");
            Thread.sleep((int) (Math.random() * 1000));  // 模拟执行时间
            System.out.println(Thread.currentThread().getName() + " has finished.");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 完成任务后,调用 countDown() 将计数减 1
            latch.countDown();
        }
    }
}

说明:

初始化 CountDownLatch:CountDownLatch(3),表示主线程会等待 3 个工作线程。
主线程等待:latch.await() 会让主线程阻塞,直到计数为 0。
工作线程完成任务后调用 countDown():每个工作线程在完成任务后调用 countDown(),使得计数值减 1。
主线程被唤醒:当所有工作线程完成任务并且调用 countDown() 后,计数值变为 0,await() 会让主线程继续执行。

使用场景:

并行任务:多个线程执行并行任务,主线程等待所有线程完成后继续执行。
批量任务的同步:比如等待多个线程读取文件后再进行合并处理等。
await() 方法在 CountDownLatch 中有一个重载版本,可以设置超时时间。 如果在指定的时间内,计数器没有变为 0,当前线程会自动退出等待状态,并继续执行。这个超时机制对于避免线程长时间等待而导致的问题(例如死锁或资源浪费)非常有用。

await(long timeout, TimeUnit unit) 方法:
timeout: 最大等待时间
unit: 超时时间的单位(如秒、毫秒等)
该方法会返回一个布尔值:

如果计数器在超时时间内到达 0,返回 true。
如果计时器在超时之前没有到达 0,返回 false。

你可能感兴趣的:(java,开发语言)