Java面试题:解释CountDownLatch, CyclicBarrier和Semaphore在并发编程中的使用

简介: Java面试题:解释CountDownLatch, CyclicBarrier和Semaphore在并发编程中的使用

在并发编程中,CountDownLatch、CyclicBarrier 和 Semaphore 是 Java 提供的同步辅助类,它们用于控制线程之间的协调。以下是每个类的基本用法和特点:

  1. CountDownLatch(倒计时门闩):
  • CountDownLatch 是一个同步辅助器,允许一个或多个线程等待一组其他线程完成操作。
  • 它通过一个计数器来工作,初始化时设定一个计数值,每当一个线程完成它的任务,计数器的值就会减一。
  • 当计数器的值到达零时,所有等待在这个 CountDownLatch 上的线程都会继续执行。
  • 一个典型用例是,当主线程需要等待多个工作线程完成它们的任务后才能继续执行。
public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        int workerCount = 5;
        CountDownLatch latch = new CountDownLatch(workerCount);

        for (int i = 0; i < workerCount; i++) {
            new Thread(() -> {
                // 模拟工作线程执行任务
                System.out.println(Thread.currentThread().getName() + " finished work.");
                latch.countDown();
            }).start();
        }

        latch.await(); // 主线程等待,直到所有工作线程完成任务
        System.out.println("All workers have finished.");
    }
}

CyclicBarrier(循环屏障):

  • CyclicBarrier 也用于线程之间的协调,但它可以重用。当一定数量的线程达到屏障时,这些线程会被阻塞,直到所有线程都到达屏障,然后所有线程才会继续执行。
  • CyclicBarrier 可以用于多轮的同步操作,当一轮操作完成后,屏障可以被重置,用于下一轮操作。
  • 一个典型用例是,当一组线程需要相互等待,直到它们都到达某个点,然后一起继续执行下一个任务。
public class CyclicBarrierExample {
    public static void main(String[] args) throws InterruptedException {
        int workerCount = 5;
        CyclicBarrier barrier = new CyclicBarrier(workerCount, () -> System.out.println("All workers are ready to proceed to the next phase."));

        for (int i = 0; i < workerCount; i++) {
            new Thread(() -> {
                // 模拟工作线程执行任务
                System.out.println(Thread.currentThread().getName() + " is ready.");
                try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}


Semaphore(信号量):

  • Semaphore 是一个计数信号量,用于控制同时访问某个特定资源的线程数量。

它通过一个许可计数来工作,线程可以通过调用 acquire() 方法来获取一个许可,当许可计数大于零时,acquire() 方法会减少许可计数并立即返回;如果许可计数为零,则调用线程会被阻塞,

  • 直到有其他线程调用 release() 方法增加许可计数。
  • Semaphore 可以用来实现流量控制,例如限制同时执行的线程数量,或者用于线程池中控制线程的并发数。
public class SemaphoreExample {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(2);

        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    // 模拟一个需要许可才能执行的任务
                    System.out.println(Thread.currentThread().getName() + " acquired a permit.");
                    // 模拟任务执行时间
                    Thread.sleep(1000);
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName() + " released a permit.");
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

这些同步辅助工具在多线程编程中非常有用,它们可以帮助开发者实现复杂的线程协调和控制逻辑。

相关文章
|
缓存 Java API
Java 面试实操指南与最新技术结合的实战攻略
本指南涵盖Java 17+新特性、Spring Boot 3微服务、响应式编程、容器化部署与数据缓存实操,结合代码案例解析高频面试技术点,助你掌握最新Java技术栈,提升实战能力,轻松应对Java中高级岗位面试。
824 0
|
算法 Java
50道java集合面试题
50道 java 集合面试题
|
Java 数据库连接 数据库
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
本文全面总结了Java核心知识点,涵盖基础语法、面向对象、集合框架、并发编程、网络编程及主流框架如Spring生态、MyBatis等,结合JVM原理与性能优化技巧,并通过一个学生信息管理系统的实战案例,帮助你快速掌握Java开发技能,适合Java学习与面试准备。
633 2
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
|
算法 Java
50道java基础面试题
50道java基础面试题
|
缓存 Java 关系型数据库
Java 面试经验总结与最新 BAT 面试资料整理含核心考点的 Java 面试经验及最新 BAT 面试资料
本文汇总了Java面试经验与BAT等大厂常见面试考点,涵盖心态准备、简历优化、面试技巧及Java基础、多线程、JVM、数据库、框架等核心技术点,并附实际代码示例,助力高效备战Java面试。
638 0
|
缓存 Cloud Native Java
Java 面试微服务架构与云原生技术实操内容及核心考点梳理 Java 面试
本内容涵盖Java面试核心技术实操,包括微服务架构(Spring Cloud Alibaba)、响应式编程(WebFlux)、容器化(Docker+K8s)、函数式编程、多级缓存、分库分表、链路追踪(Skywalking)等大厂高频考点,助你系统提升面试能力。
1814 0
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!