并发工具类:如何在JDK 8、17与21中使用CountDownLatchSemaphoreCyclicBarrier

粉丝提问:

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

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

Java进阶之路:必知必会的核心知识点与JDK8、JDK17、JDK21版本对比


作者简介

猫头虎是谁?

大家好,我是 猫头虎,猫头虎技术团队创始人,也被大家称为猫哥。我目前是COC北京城市开发者社区主理人COC西安城市开发者社区主理人,以及云原生开发者社区主理人,在多个技术领域如云原生、前端、后端、运维和AI都具备丰富经验。

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用方法、前沿科技资讯、产品评测、产品使用体验,以及产品优缺点分析、横向对比、技术沙龙参会体验等。我的分享聚焦于云服务产品评测、AI产品对比、开发板性能测试和技术报告

目前,我活跃在CSDN、51CTO、腾讯云、阿里云开发者社区、华为云开发者社区、知乎、微信公众号、视频号、抖音、B站、小红书等平台,全网粉丝已超过30万。我所有平台的IP名称统一为猫头虎猫头虎技术团队

我希望通过我的分享,帮助大家更好地掌握和使用各种技术产品,提升开发效率与体验。


作者名片 ✍️

  • 博主猫头虎
  • 全网搜索关键词猫头虎
  • 作者微信号Libin9iOak
  • 作者公众号猫头虎技术团队
  • 更新日期2024年12月16日
  • 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能!

加入我们AI共创团队 🌐

加入猫头虎的共创圈,一起探索编程世界的无限可能! 🚀


正文


一、并发工具类基础概念

1. CountDownLatch

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

2. Semaphore

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

3. CyclicBarrier

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


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

工具类JDK 8JDK 17JDK 21
CountDownLatch基本功能实现性能优化:减少竞争锁集成虚拟线程更高效
Semaphore基础信号量实现增加公平性支持与虚拟线程兼容性提升
CyclicBarrier基础同步实现增强异常处理性能提升:通过虚拟线程实现大规模并发

三、工具类的使用与示例

1. CountDownLatch 示例:多线程初始化

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 示例:限制资源访问

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 示例:并发任务分块计算

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

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中的虚拟线程将彻底改变并发编程方式:

  • 大规模线程管理变得更简单。
  • 并发工具类性能显著提升。
  • 开发者可以更专注于业务逻辑而非线程管理。

更多Java技术干货,欢迎加入猫头虎的AI技术社群,与60万开发者共同成长!

粉丝福利


👉 更多信息:有任何疑问或者需要进一步探讨的内容,欢迎点击文末名片获取更多信息。我是猫头虎,期待与您的交流! 🦉💬

🌐 第一板块:

https://zhaimengpt1.kimi.asia/list

💳 第二板块:最稳定的AI全平台可支持平台


联系我与版权声明 📩

  • 联系方式
    • 微信: Libin9iOak
    • 公众号: 猫头虎技术团队
  • 版权声明
    本文为原创文章,版权归作者所有。未经许可,禁止转载。更多内容请访问猫头虎的博客首页

点击✨⬇️下方名片⬇️✨,加入猫头虎AI共创社群,交流AI新时代变现的无限可能。一起探索科技的未来,共同成长。🚀

Logo

欢迎加入西安开发者社区!我们致力于为西安地区的开发者提供学习、合作和成长的机会。参与我们的活动,与专家分享最新技术趋势,解决挑战,探索创新。加入我们,共同打造技术社区!

更多推荐