美文网首页
深耕 JDK 源码 - CountDownLatch

深耕 JDK 源码 - CountDownLatch

作者: 西瓜汁and柠檬水 | 来源:发表于2023-04-21 19:10 被阅读0次

    多线程编程中,线程之间的协同与同步是一种常见的需求。Java 提供了许多用于实现线程同步的工具,其中之一就是 CountDownLatch。CountDownLatch 是一个简单而强大的多线程同步工具,可以帮助开发者实现一组线程在某个事件完成后再同时执行的需求。本文将详细介绍 CountDownLatch 的实现原理、用法以及相关的代码解释。

    一、实现原理

    CountDownLatch 内部维护了一个计数器,通过其构造方法指定初始计数值。计数器的值在 CountDownLatch 对象创建后是不可修改的。每当一个线程完成了某个任务时,可以调用 CountDownLatch 的 countDown() 方法,将计数值减一。当计数值变为零时,所有在 CountDownLatch 上等待的线程会被唤醒,可以继续执行。

    CountDownLatch 的实现原理可以简单描述如下:

    1. 创建 CountDownLatch 对象时,需要指定初始计数值。
    2. 每个线程在完成任务后,通过调用 countDown() 方法将计数值减一。
    3. 当计数值变为零时,所有等待的线程会被唤醒,可以继续执行后续的逻辑。

    二、用法

    CountDownLatch 常用于一组线程中,有一个或多个线程需要等待其他线程完成某个任务后再继续执行。以下是 CountDownLatch 的一般用法:

    1. 创建 CountDownLatch 对象,并指定初始计数值:
    CountDownLatch latch = new CountDownLatch(3); // 初始计数值为 3
    

    这里创建了一个 CountDownLatch 对象 latch,并指定初始计数值为 3。

    1. 创建需要等待的线程,并在其任务完成后调用 countDown() 方法:
    // 线程1
    Thread thread1 = new Thread(() -> {
        // 执行任务
        latch.countDown(); // 计数值减一
    });
    
    // 线程2
    Thread thread2 = new Thread(() -> {
        // 执行任务
        latch.countDown(); // 计数值减一
    });
    
    // 线程3
    Thread thread3 = new Thread(() -> {
        // 执行任务
        latch.countDown(); // 计数值减一
    });
    

    这里创建了三个线程 thread1、thread2、thread3,并在其任务完成后分别调用了 countDown() 方法,将计数值减一。

    1. 创建需要等待的线程,并在其任务完成后调用 await() 方法来等待其他线程完成任务:
    // 等待线程1、线程2、线程3完成任务
    try {
        latch.await(); // 等待计数值变为零
    } catch (InterruptedException e) {
        // 处理中断异常
    }
    

    这里调用了 await() 方法,它会阻住当前线程,直到计数值变为零,即所有等待的线程都完成了任务。

    1. 完整示例代码:

    下面是一个完整的示例代码,演示了 CountDownLatch 的使用:

    import java.util.concurrent.CountDownLatch;
    
    public class CountDownLatchExample {
    
        public static void main(String[] args) {
            // 创建 CountDownLatch 对象,并指定初始计数值为 3
            CountDownLatch latch = new CountDownLatch(3);
    
            // 创建线程1
            Thread thread1 = new Thread(() -> {
                System.out.println("Thread 1 is running...");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread 1 finished.");
                latch.countDown(); // 计数值减一
            });
    
            // 创建线程2
            Thread thread2 = new Thread(() -> {
                System.out.println("Thread 2 is running...");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread 2 finished.");
                latch.countDown(); // 计数值减一
            });
    
            // 创建线程3
            Thread thread3 = new Thread(() -> {
                System.out.println("Thread 3 is running...");
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread 3 finished.");
                latch.countDown(); // 计数值减一
            });
    
            // 启动线程
            thread1.start();
            thread2.start();
            thread3.start();
    
            try {
                latch.await(); // 等待计数值变为零
                System.out.println("All threads finished. Proceeding to next step.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    运行以上代码,会输出类似以下的结果:

    Thread 3 is running...
    Thread 1 is running...
    Thread 2 is running...
    Thread 3 finished.
    Thread 1 finished.
    Thread 2 finished.
    All threads finished. Proceeding to next step.
    

    三、总结

    CountDownLatch 是一个简单而强大的多线程同步工具,可以帮助开发者实现一组线程在某个事件完成后再同时执行的需求。它的实现原理简单明了,通过维护一个计数器来实现线程之间的同步。通过调用 countDown() 方法将计数值减一,当计数值变为零时,所有等待的线程会被唤醒。CountDownLatch 在实际开发中可以应用于各种场景,例如等待多个线程完成初始化、等待多个线程同时开始执行某个任务等。使用 CountDownLatch 可以使多线程编程更加简洁、高效和安全。

    相关文章

      网友评论

          本文标题:深耕 JDK 源码 - CountDownLatch

          本文链接:https://www.haomeiwen.com/subject/mcejjdtx.html