CyclicBarrier 和 CountDownLatch

举报
赵KK日常技术记录 发表于 2023/08/14 17:40:30 2023/08/14
【摘要】 引言在多线程编程中,我们经常会遇到一些需要线程间协同工作的场景。CyclicBarrier 和 CountDownLatch 就是两种常用的同步工具,它们能够帮助我们实现线程间的协调和同步。本文将深入探讨这两种同步工具的实现原理,并附上代码演示。 CyclicBarrier 的实现原理CyclicBarrier 可以用来等待一组线程到达一个共同的栅栏点,然后同时开始执行下一步任务。它的内部实...

引言

在多线程编程中,我们经常会遇到一些需要线程间协同工作的场景。CyclicBarrierCountDownLatch 就是两种常用的同步工具,它们能够帮助我们实现线程间的协调和同步。本文将深入探讨这两种同步工具的实现原理,并附上代码演示。

CyclicBarrier 的实现原理

CyclicBarrier 可以用来等待一组线程到达一个共同的栅栏点,然后同时开始执行下一步任务。它的内部实现主要依靠一个计数器和一个等待队列。

当我们创建一个 CyclicBarrier 实例时,我们需要传入一个整数值,表示需要等待的线程数量。当每个线程调用 await() 方法时,计数器会递减,然后线程会进入等待状态。当计数器达到零时,所有等待的线程都会被释放,可以继续执行下一步任务,同时计数器会被重置,可以被下一轮使用。

以下是一个简化的 CyclicBarrier 实现的示例代码:

public class CyclicBarrier {
    private int parties;
    private int count;

    public CyclicBarrier(int parties) {
        this.parties = parties;
        this.count = parties;
    }

    public synchronized void await() throws InterruptedException {
        count--;

        if (count > 0) {
            this.wait();
        } else {
            count = parties;
            this.notifyAll();
        }
    }
}

CountDownLatch 的实现原理

CountDownLatch 是另一种线程同步工具,它允许一个或多个线程等待其他线程完成操作后再继续执行。其实现原理较为简单,主要依赖于一个计数器和线程等待机制。

在创建 CountDownLatch 实例时,需要传入一个整数值,表示需要等待的操作数。每个操作完成后,调用 countDown() 方法,计数器会递减。等待的线程可以通过调用 await() 方法来阻塞,直到计数器减到零。

以下是一个简单的 CountDownLatch 实现的示例代码:

public class CountDownLatch {
    private int count;

    public CountDownLatch(int count) {
        this.count = count;
    }

    public synchronized void countDown() {
        count--;

        if (count == 0) {
            this.notifyAll();
        }
    }

    public synchronized void await() throws InterruptedException {
        while (count > 0) {
            this.wait();
        }
    }
}

代码演示

现在让我们通过一个示例场景来演示如何使用 CyclicBarrierCountDownLatch

假设我们有一个多线程任务,需要等待所有线程都完成后再继续进行。首先,我们可以使用 CountDownLatch 来实现这个需求:

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        int threadCount = 3;
        CountDownLatch latch = new CountDownLatch(threadCount);

        for (int i = 0; i < threadCount; i++) {
            Thread thread = new Thread(() -> {
                // 模拟线程执行
                System.out.println("Thread " + Thread.currentThread().getId() + " is working.");
                latch.countDown();
            });
            thread.start();
        }

        latch.await();
        System.out.println("All threads have finished.");
    }
}

接下来,我们使用 CyclicBarrier 来实现一个多线程任务的同步:

public class CyclicBarrierDemo {
    public static void main(String[] args) throws InterruptedException {
        int threadCount = 3;
        CyclicBarrier barrier = new CyclicBarrier(threadCount);

        for (int i = 0; i < threadCount; i++) {
            Thread thread = new Thread(() -> {
                // 模拟线程执行
                System.out.println("Thread " + Thread.currentThread().getId() + " is working.");
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread " + Thread.currentThread().getId() + " continues.");
            });
            thread.start();
        }
    }
}

结论

CyclicBarrierCountDownLatch 都是用于线程同步的重要工具,分别适用于不同的场景。CyclicBarrier 可以用于多个线程等待彼此达到一个栅栏点,然后同时继续执行,而 CountDownLatch 则用于一个或多个线程等待其他线程完成后再继续执行。了解它们的实现原理和使用方法,将有助于我们在多线程编程中更好地处理并发场景。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。