14-1.Java 多线程编程之 CountDownLatch(CountDownLatch 核心功能、CountDownLatch 核心方法、CountDownLatch 实例实操)

一、CountDownLatch

  1. CountDownLatch 是 Java 并发编程中的一个同步工具类,用于协调多个线程的执行

  2. CountDownLatch 允许一个或多个线程等待其他线程完成操作后再继续执行

  3. CountDownLatch 的核心思想是通过一个计数器来实现线程的等待和通知机制


二、CountDownLatch 核心功能

1、计数器
  1. CountDownLatch 内部维护一个计数器,初始值为指定的正整数

  2. 每当一个线程完成任务时,调用 countDown 方法将计数器减 1

  3. 当计数器减到 0 时,所有等待的线程会被唤醒并继续执行

2、等待机制
  1. 线程可以调用 await 方法等待计数器减到 0

  2. 如果计数器不为 0,调用 await 方法的线程会被阻塞,直到计数器减到 0


三、CountDownLatch 核心方法

CountDownLatch(int count)
  1. 构造方法,初始化计数器
void await() throws InterruptedException
  1. 等待计数器减到 0,如果计数器不为 0,则当前线程会被阻塞
boolean await(long timeout, TimeUnit unit) throws InterruptedException
  1. 等待计数器减到 0,最多等待指定时间,如果超时返回 false,否则返回 true
void countDown()
  1. 将计数器减 1,如果计数器减到 0,则唤醒所有等待的线程
long getCount()
  1. 返回当前计数器的值

四、CountDownLatch 实例实操

1、主线程等待子线程完成任务
int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount);

for (int i = 1; i <= threadCount; i++) {
    new Thread(() -> {
        try {
            System.out.println(Thread.currentThread().getName() + " is working...");
            Thread.sleep((long) (Math.random() * 1000)); // 模拟任务执行时间
            System.out.println(Thread.currentThread().getName() + " has finished");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            latch.countDown(); // 任务完成,计数器减 1
        }
    }, "Thread-" + i).start();
}

System.out.println("Main thread is waiting for all threads to finish...");
try {
    latch.await(); // 主线程等待计数器减到 0
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println("All threads have finished. Main thread continues");
  • 输出结果
Main thread is waiting for all threads to finish...
Thread-3 is working...
Thread-2 is working...
Thread-1 is working...
Thread-1 has finished
Thread-3 has finished
Thread-2 has finished
All threads have finished. Main thread continues
2、多线程任务同步
int threadCount = 3;
CountDownLatch startLatch = new CountDownLatch(1); // 用于同步开始
CountDownLatch endLatch = new CountDownLatch(threadCount); // 用于等待结束

for (int i = 1; i <= threadCount; i++) {
    new Thread(() -> {
        try {
            System.out.println(Thread.currentThread().getName() + " is ready");
            startLatch.await(); // 等待主线程发出开始信号
            System.out.println(Thread.currentThread().getName() + " is running...");
            Thread.sleep((long) (Math.random() * 1000)); // 模拟任务执行时间
            System.out.println(Thread.currentThread().getName() + " has finished");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            endLatch.countDown(); // 任务完成,计数器减 1
        }
    }, "Thread-" + i).start();
}

try {
    Thread.sleep(1000); // 模拟主线程准备时间
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println("Main thread signals to start");
startLatch.countDown(); // 发出开始信号

System.out.println("Main thread is waiting for all threads to finish...");
try {
    endLatch.await(); // 主线程等待所有线程完成任务
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println("All threads have finished. Main thread continues");
  • 输出结果
Thread-1 is ready
Thread-3 is ready
Thread-2 is ready
Main thread signals to start
Main thread is waiting for all threads to finish...
Thread-1 is running...
Thread-3 is running...
Thread-2 is running...
Thread-1 has finished
Thread-2 has finished
Thread-3 has finished
All threads have finished. Main thread continues
3、分阶段任务处理
int threadCount = 3;
CountDownLatch phaseLatch = new CountDownLatch(threadCount);

for (int i = 1; i <= threadCount; i++) {
    new Thread(() -> {
        try {
            System.out.println(Thread.currentThread().getName() + " is working on phase 1...");
            Thread.sleep((long) (Math.random() * 1000)); // 模拟任务执行时间
            System.out.println(Thread.currentThread().getName() + " has finished phase 1");
            phaseLatch.countDown(); // 第一阶段完成,计数器减 1

            phaseLatch.await(); // 等待所有线程完成第一阶段
            System.out.println(Thread.currentThread().getName() + " is working on phase 2...");
            Thread.sleep((long) (Math.random() * 1000)); // 模拟任务执行时间
            System.out.println(Thread.currentThread().getName() + " has finished phase 2");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, "Thread-" + i).start();
}
  • 输出结果
Thread-1 is working on phase 1...
Thread-3 is working on phase 1...
Thread-2 is working on phase 1...
Thread-3 has finished phase 1
Thread-2 has finished phase 1
Thread-1 has finished phase 1
Thread-3 is working on phase 2...
Thread-1 is working on phase 2...
Thread-2 is working on phase 2...
Thread-2 has finished phase 2
Thread-1 has finished phase 2
Thread-3 has finished phase 2

你可能感兴趣的:(Java,-,基础入门精美笔记,java,开发语言,后端,笔记,java-ee,后端开发,学习)