细谈CountDownLatch和CyclicBarrier

今天和大家探讨最近的面试题,好久没有面试了,所以在此记录一下。本篇文章主要讲解CyclicBarrier和CountDownLatch的知识。。

CountDownLatch

CountDownLatch是一种同步工具类,它允许一个或多个线程等待其他线程完成操作。CountDownLatch,它是由java.util.concurrent.CountDownLatch类实现的。

CountDownLatch的主要功能是提供一个计数器,初始化为一个正整数,表示需要等待的线程数量。当一个线程完成操作后,计数器会减一。当计数器减为零时,所有等待的线程都会被释放,然后继续执行后续操作。

举个栗子:

java 复制代码
import java.util.concurrent.CountDownLatch;  
  
public class CountDownLatchExample {  
    public static void main(String[] args) throws InterruptedException {  
        final int totalThread = 5;//计数器  
        CountDownLatch latch = new CountDownLatch(totalThread);  
  
        for (int i = 0; i < totalThread; i++) {  
            new Thread(() -> {  
                System.out.println("线程" + Thread.currentThread().getId() + "准备进入等待状态");  
                try {  
                    latch.await();  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                System.out.println("线程" + Thread.currentThread().getId() + "继续执行后续操作");  
            }).start();  
        }  
  
        // 主线程等待所有子线程完成操作  
        Thread.sleep(2000);  
        latch.countDown(); // 手动减少计数器  
    }  
}

代码翻译:我们创建了一个CountDownLatch实例,初始计数器为5,表示需要等待5个子线程完成操作。 然后我们创建5个子线程,每个子线程在进入等待状态之前都会打印一条消息,然后调用latch.await()方法等待其他子线程到达屏障点。

当所有子线程都到达屏障点后,主线程会继续执行后续操作。如果在调用await()方法时线程被中断或者CountDownLatch实例被破坏,那么会抛出InterruptedException异常。

CountDownLatch的优点是可以让一组线程互相等待,避免了忙等待和资源浪费的问题。同时,CountDownLatch也适用于多线程协作的场景,例如在分布式系统中用于控制各个节点的同步操作。

CyclicBarrier

CyclicBarrier,它是一种同步工具类,它允许一组线程互相等待,直到所有线程都达到某个公共屏障点。一旦所有线程都到达这个屏障点,它们就可以继续执行后续的操作。CyclicBarrier字面意思是循环的屏障,因为它可以重复使用,不像一次性使用的CountDownLatch

CyclicBarrier是由java.util.concurrent.CyclicBarrier类实现的。它提供了一个构造函数,可以接受一个整数参数,表示需要等待的线程数量。当线程到达屏障点时,它会被阻塞,直到所有其他线程都到达屏障点。一旦所有线程到达屏障点,它们都会被释放并继续执行。

再次举个栗子:

java 复制代码
import java.util.concurrent.BrokenBarrierException;  
import java.util.concurrent.CyclicBarrier;  
  
public class CyclicBarrierExample {  
    public static void main(String[] args) {  
        final int totalThread = 5;  
        CyclicBarrier cyclicBarrier = new CyclicBarrier(totalThread);  
  
        for (int i = 0; i < totalThread; i++) {  
            new Thread(() -> {  
                System.out.println("线程" + Thread.currentThread().getId() + "准备进入屏障");  
                try {  
                    cyclicBarrier.await();  
                } catch (InterruptedException | BrokenBarrierException e) {  
                    e.printStackTrace();  
                }  
                System.out.println("线程" + Thread.currentThread().getId() + "通过屏障");  
            }).start();  
        }  
    }  
}

代码翻译:我们创建了一个CyclicBarrier实例,需要等待5个线程到达屏障点。

然后我们创建5个线程,每个线程在到达屏障点之前都会打印一条消息,然后调用cyclicBarrier.await()方法等待其他线程到达屏障点。

一旦所有线程都到达屏障点,它们就会被释放并打印一条消息表示它们已经通过屏障。如果在调用await()方法时线程被中断或者CyclicBarrier实例被破坏,那么会抛出InterruptedException或者BrokenBarrierException异常。

文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。

相关推荐
yuuki2332336 小时前
【C语言】文件操作(附源码与图片)
c语言·后端
IT_陈寒6 小时前
Python+AI实战:用LangChain构建智能问答系统的5个核心技巧
前端·人工智能·后端
无名之辈J7 小时前
系统崩溃(OOM)
后端
码农刚子7 小时前
ASP.NET Core Blazor简介和快速入门 二(组件基础)
javascript·后端
间彧7 小时前
Java ConcurrentHashMap如何合理指定初始容量
后端
catchadmin7 小时前
PHP8.5 的新 URI 扩展
开发语言·后端·php
少妇的美梦7 小时前
Maven Profile 教程
后端·maven
白衣鸽子7 小时前
RPO 与 RTO:分布式系统容灾的双子星
后端·架构
Jagger_7 小时前
SOLID原则与设计模式关系详解
后端
间彧7 小时前
Java: HashMap底层源码实现详解
后端