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

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

并发编程中,CountDownLatchCyclicBarrierSemaphore 是 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();
        }
    }
}

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

相关文章
|
28天前
|
SQL Java Unix
Android经典面试题之Java中获取时间戳的方式有哪些?有什么区别?
在Java中获取时间戳有多种方式,包括`System.currentTimeMillis()`(毫秒级,适用于日志和计时)、`System.nanoTime()`(纳秒级,高精度计时)、`Instant.now().toEpochMilli()`(毫秒级,ISO-8601标准)和`Instant.now().getEpochSecond()`(秒级)。`Timestamp.valueOf(LocalDateTime.now()).getTime()`适用于数据库操作。选择方法取决于精度、用途和时间起点的需求。
31 3
|
1月前
|
缓存 监控 算法
Java面试题:描述Java垃圾回收的基本原理,以及如何通过代码优化来协助垃圾回收器的工作
Java面试题:描述Java垃圾回收的基本原理,以及如何通过代码优化来协助垃圾回收器的工作
57 8
|
1月前
|
NoSQL Java 应用服务中间件
Java高级面试题
Java高级面试题
|
1月前
|
网络协议 安全 前端开发
java面试题
java面试题
|
1月前
|
NoSQL Java 关系型数据库
常见Java面试题
常见Java面试题
|
11月前
|
存储 Java 程序员
Java面试题日积月累(数据库30道)
Java面试题日积月累(数据库30道)
58 0
|
1月前
|
SQL 安全 Java
Java面试题:什么是JDBC以及如何在Java中使用它进行数据库操作?
Java面试题:什么是JDBC以及如何在Java中使用它进行数据库操作?
27 0
|
1月前
|
druid Java 数据库连接
Java面试题:解释数据库连接池的概念及其作用,讨论常见的连接池实现。
Java面试题:解释数据库连接池的概念及其作用,讨论常见的连接池实现。
39 0
|
1月前
|
SQL Java 关系型数据库
Java面试题:描述JDBC的工作原理,包括连接数据库、执行SQL语句等步骤。
Java面试题:描述JDBC的工作原理,包括连接数据库、执行SQL语句等步骤。
35 0
|
1月前
|
SQL 监控 Java
Java面试题:简述数据库性能优化的常见手段,如索引优化、SQL语句优化等。
Java面试题:简述数据库性能优化的常见手段,如索引优化、SQL语句优化等。
59 0