首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >并发工具类:如何在JDK 8、17与21中使用CountDownLatch、Semaphore和CyclicBarrier?

并发工具类:如何在JDK 8、17与21中使用CountDownLatch、Semaphore和CyclicBarrier?

作者头像
猫头虎
发布2024-12-24 08:27:37
发布2024-12-24 08:27:37
36800
代码可运行
举报
运行总次数:0
代码可运行
并发工具类:如何在JDK 8、17与21中使用CountDownLatchSemaphoreCyclicBarrier

粉丝提问:

在Java并发编程中,CountDownLatchSemaphoreCyclicBarrier是常见的同步工具。它们在JDK 8、17和21中有何差异?如何正确使用它们?

本文将为你全面解析这些工具类的原理、使用方法及其在不同Java版本中的优化点,助你轻松解决并发任务中的同步问题。

正文

一、并发工具类基础概

1. CountDownLatch

作用:允许一个线程等待多个线程完成任务后再继续执行。 典型场景:启动多个线程并等待它们完成初始化。

2. Semaphore

作用:控制同时访问特定资源的线程数量。 典型场景:限制访问某个资源的并发线程数,例如数据库连接池。

3. CyclicBarrier

作用:让一组线程到达同步点后再一起继续执行。 典型场景:实现多线程协同工作,例如并行任务分块计算。


二、各工具类在JDK 8、17和21中的优化点

工具类

JDK 8

JDK 17

JDK 21

CountDownLatch

基本功能实现

性能优化:减少竞争锁

集成虚拟线程更高效

Semaphore

基础信号量实现

增加公平性支持

与虚拟线程兼容性提升

CyclicBarrier

基础同步实现

增强异常处理

性能提升:通过虚拟线程实现大规模并发


三、工具类的使用与示例

1. CountDownLatch 示例:多线程初始化
代码语言:javascript
代码运行次数:0
运行
复制
import java.util.concurrent.CountDownLatch;

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

        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " 初始化完成");
                latch.countDown(); // 每个线程完成后减少计数
            }).start();
        }

        latch.await(); // 等待所有线程完成
        System.out.println("所有线程初始化完成,继续执行主任务");
    }
}
2. Semaphore 示例:限制资源访问
代码语言:javascript
代码运行次数:0
运行
复制
import java.util.concurrent.Semaphore;

public class SemaphoreExample {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(2); // 允许同时访问的线程数为2

        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire(); // 获取许可
                    System.out.println(Thread.currentThread().getName() + " 获取资源");
                    Thread.sleep(1000); // 模拟资源使用
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release(); // 释放许可
                    System.out.println(Thread.currentThread().getName() + " 释放资源");
                }
            }).start();
        }
    }
}
3. CyclicBarrier 示例:并发任务分块计算
代码语言:javascript
代码运行次数:0
运行
复制
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {
    public static void main(String[] args) {
        int parties = 3;
        CyclicBarrier barrier = new CyclicBarrier(parties, () -> System.out.println("所有线程已到达屏障,开始下一步"));

        for (int i = 0; i < parties; i++) {
            new Thread(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 执行任务");
                    Thread.sleep(1000); // 模拟任务执行
                    barrier.await(); // 等待其他线程
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

四、JDK 21中虚拟线程的优势

在JDK 21中,虚拟线程的引入显著提升了上述工具类的并发性能:

  • CountDownLatch 与虚拟线程:支持大规模线程同步,减少线程资源消耗。
  • Semaphore 与虚拟线程:避免传统线程池管理带来的资源浪费。
  • CyclicBarrier 与虚拟线程:更适合超高并发的任务分解与协同。
虚拟线程的结合示例:CountDownLatch
代码语言:javascript
代码运行次数:0
运行
复制
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;

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

        var executor = Executors.newVirtualThreadPerTaskExecutor();

        for (int i = 0; i < threadCount; i++) {
            executor.execute(() -> {
                System.out.println(Thread.currentThread().getName() + " 虚拟线程任务完成");
                latch.countDown();
            });
        }

        latch.await();
        System.out.println("所有虚拟线程任务完成");
        executor.close();
    }
}

五、常见问题 Q&A

Q:虚拟线程是否完全替代传统线程? A:虚拟线程在高并发任务中表现出色,但对于重计算任务,仍需传统线程池支持。

Q:CyclicBarrier 与 Semaphore 的选择标准是什么? A:CyclicBarrier 适用于任务协同,Semaphore 用于资源访问限制。根据具体场景选择。

六、总结与趋势展望

趋势展望: JDK 21中的虚拟线程将彻底改变并发编程方式:

  • 大规模线程管理变得更简单。
  • 并发工具类性能显著提升。
  • 开发者可以更专注于业务逻辑而非线程管理。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 并发工具类:如何在JDK 8、17与21中使用CountDownLatch、Semaphore和CyclicBarrier?
  • 正文
    • 一、并发工具类基础概
      • 1. CountDownLatch
      • 2. Semaphore
      • 3. CyclicBarrier
    • 二、各工具类在JDK 8、17和21中的优化点
    • 三、工具类的使用与示例
      • 1. CountDownLatch 示例:多线程初始化
      • 2. Semaphore 示例:限制资源访问
      • 3. CyclicBarrier 示例:并发任务分块计算
    • 四、JDK 21中虚拟线程的优势
      • 虚拟线程的结合示例:CountDownLatch
    • 五、常见问题 Q&A
    • 六、总结与趋势展望
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档