首页 > 其他分享 >三个常见JUC辅助类

三个常见JUC辅助类

时间:2024-11-04 18:16:18浏览次数:3  
标签:JUC 辅助 常见 屏障 线程 CountDownLatch Semaphore new CyclicBarrier

三个常见JUC辅助类

1. 减少计数(CountDownLatch)

​ 通过一个计数器来管理需要等待的线程数量,当这些线程都完成各自的任务后(即计数器递减到0),才会允许其他等待的线程继续执行。

步骤:

  1. 定义 CountDownLatch类,并设置一个固定值
  2. 在需要计数的位置加上 countDown() 方法
  3. 使用 await() 方法控制计数到达0时的后续步骤
private static void countDownLatchDemo() throws InterruptedException {
    CountDownLatch count = new CountDownLatch(NUM);
    for (int i = 1; i <= 7; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "同学走出教室");
            count.countDown();
        }, String.valueOf(i)).start();
    }
    //count减为0,执行await后面内容
    count.await();
    System.out.println("班长锁门!");
}

特点与注意事项:

  • CountDownLatch的计数器只能减少到0,一旦减少到0后,无法重置计数器。因此,CountDownLatch只能使用一次
  • 一旦计数器的值减少到0,等待线程将被释放,无法再次等待。因此,在使用CountDownLatch时需要注意其这一特性。
  • CountDownLatch可以根据实际需求设置等待的线程数量,提供了灵活的线程同步与协调机制。

2. 循环栅栏(CyclicBarrier)

​ 允许一组线程互相等待,直到所有线程都到达一个公共屏障点。在继续执行之前,所有线程都会被阻塞在这个屏障点上。

步骤:

  1. 定义CyclicBarrier类,指定循环到达的阈值及到达阈值后执行的内容
  2. 在需要判断阈值的地方调用 await() 方法
private static void cyclicBarrierDemo() {
    //定义循环栅栏类 param1(指定的数量) param2(到达数量后执行的内容)
    CyclicBarrier barrier = new CyclicBarrier(NUM, () ->{
        System.out.println("一起去救爷爷!");
    });
    for (int i = 1; i <= 7; i++) {
        new Thread(() ->{
            System.out.println(Thread.currentThread().getName() + "娃诞生");
            try {
                barrier.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (BrokenBarrierException e) {
                throw new RuntimeException(e);
            }
        }, String.valueOf(i)).start();
    }
}

特点:

  • 线程同步:它提供了一种机制,使得多个线程能够在某个点上同步它们的执行。这对于需要并行处理多个任务,并在所有任务都完成后才进行下一步操作的场景非常有用。
  • 结果合并或后续处理:在屏障点,可以指定一个可选的屏障动作(barrier action),当所有线程都到达屏障点时,这个屏障动作会被执行。这通常用于合并各个线程的结果,或者进行一些后续的准备工作。
  • 可重用性CyclicBarrier可重用的,这意味着一旦所有线程都通过了屏障点,并且屏障动作(如果有的话)被执行完毕,CyclicBarrier 会自动重置,以便下一轮线程可以继续使用它进行同步。
  • 线程管理:它提供了一种方式来管理参与同步的线程数量,如果某个线程因为某些原因(如中断或超时)未能到达屏障点,那么CyclicBarrier 可以提供一个机制来处理这种情况,比如通过抛出异常来通知其他线程。

CountDownLatch 和 CyclicBarrier 的区别

总结以下两点:

  1. 使用场景

    CountDownLatch 更适用于需要等待一组线程完成某个操作的场景

    CyclicBarrier 更适用于需要多线程并行处理然后合并结果的场景

  2. 循环特性

    CountDownLatch 是一个一次性工具,计数器一旦变为0就不能再被重置

    CyclicBarrier 允许循环等待,即当一组线程通过屏障点后,可以继续等待下一组线程到达屏障点

3. 信号灯(Semaphore)

​ 用于控制对共享资源的访问数量

步骤:

  1. 定义 Semaphore 类,设置可同时拿到许可的数量
  2. 使用 **acquire() **方法获取许可,并执行获取许可后的操作
  3. 使用 release() 方法释放线程
private static void semaphoreDemo() {
    Semaphore semaphore = new Semaphore(3);
    for (int i = 1; i <= 7; i++) {
        new Thread(() ->{
            try {
                //获取许可
                semaphore.acquire();
                System.out.println(Thread.currentThread().getName() + "车抢到了车位!");
                //假定停车时间
                TimeUnit.SECONDS.sleep(new Random().nextInt(3));
                System.out.println(Thread.currentThread().getName() + "车离开了");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                semaphore.release();
            }
        }, String.valueOf(i)).start();
    }
}

特点:

  • 限制并发数:Semaphore通过一个计数器来跟踪当前可用的许可数量,从而限制能够同时访问某个特定资源的线程数量。当线程数量达到Semaphore设定的上限时,额外的线程将会被阻塞,直到有线程释放许可。
  • 资源保护:在多线程环境下,多个线程可能同时尝试访问或修改同一个资源,这可能导致数据不一致或资源损坏。Semaphore通过限制同时访问资源的线程数量,可以保护资源免受并发访问的干扰。
  • 协调线程:Semaphore提供了一种机制,使得线程之间可以相互协调,以确保它们按照预期的顺序或数量访问共享资源。这有助于避免竞争条件和死锁等问题。
  • 实现公平性:Semaphore可以选择性地支持公平性策略,这意味着线程将按照它们请求许可的顺序来获得许可。这有助于避免线程饥饿问题,即某个线程长时间无法获得所需资源的情况。

标签:JUC,辅助,常见,屏障,线程,CountDownLatch,Semaphore,new,CyclicBarrier
From: https://blog.csdn.net/Cleverguyyy/article/details/143489945

相关文章

  • 常见的软件安全性缺陷和漏洞
    软件的安全有很多方面的内容,主要的安全问题是由软件本身的漏洞造成的,下面介绍常见的软件安全性缺陷和漏洞。1、缓冲区溢出缓冲区溢出已成为软件安全的头号公敌,许多实际中的安全问题都与它有关。造成缓冲区溢出问题通常有以下两种原因。1)设计空间的转换规则的校验问题即缺乏......
  • python-16-常见高级函数
    python-16-常见高级函数一.说明python中的基础系列中的关于函数部分,还有一些特殊函数叫高级函数,在真实项目中开发使用频率较高,说句人话,就是真香实用!。二.定义在Python中,高阶函数是指接受其他函数作为参数或返回一个函数的函数。高阶函数使得我们能够以更灵活和简洁的方......
  • 常见的100个Shell命令(非常详细)零基础入门到精通,收藏这一篇就够了
    在大多数的Linux和Unix系统、及其他类Unix系统中,Shell是用户与操作系统内核交互的主要方式。作为一种强大的命令行解释器,它也支持编程功能,用户可以写脚本来处理各种任务。熟悉shell脚本,首先要对shell指令熟悉,今天就简单介绍常用的**100个Shell命令**,希望对你有所帮助!【文......
  • Apache 配置出错常见问题及解决方法
    Apache配置出错常见问题及解决方法一、端口被占用问题问题描述:在启动Apache时,出现“Addressalreadyinuse”或类似的错误提示,这意味着Apache想要使用的端口已经被其他程序占用,导致Apache无法正常启动。原因分析:系统中已经有其他的应用程序在使用Apache......
  • 常见的开源软件许可证及其应用案例
    目录引言开源的定义开源许可证的种类常见的开源许可证及其应用案例结论引言开源软件在过去几十年中迅速发展,已经成为软件开发的重要组成部分。开源不仅仅是一种技术模式,更是一种文化和社区精神。本文将详细介绍开源的定义、开源许可证的种类以及常见的开源许可证,并结......
  • docker 安装和常见命令
    文章目录目录一、Docker是什么?二、CentOsyum源配置三、docker安装1.安装docker前的环境准备2.配置dockeryum源3.docker安装4.docker启动/重启/关闭/开机自启5.查看dockeryum配置是否成 6.docker卸载四、docker基础命令五、数据卷常见操作六、网络操作一、......
  • git常见命令总结
    文章目录什么是git? 远程仓库相关操作初始化git仓库查看状态信息工作区<=>暂存区相关操作暂存区<=>本地存储仓库。配置作者的信息分支相关操作标签操作常见错误什么是git?Git是一个分布式版本控制系统,由LinusTorvalds于2005年创建,最初是为了更好地管理......
  • 【Spring编程常见错误50例】02.原型bean被固定
    Demo如下所示,通过将ServiceImplScope设置为原型,但是在每次调用接口获取的时候返回的都是同一个实例。显然是不符合我们预期。@RequestMapping(path="/hiScope",method=RequestMethod.GET)publicStringhiScope(){return"hiScope"+serviceImpl......
  • Linux常见指令大全(必要+知识点)
    目录 ls指令☑️在Windows中会自动显示当前目录当中的所有子目录与文件,但是在Linux中要用到ls指令。语法:ls[选项][目录或文件] 功能:对于目录,该命令列出该目录下的所有子目录与文件。对于文件,将列出文件名以及其他信息。 目录下所有文件(蓝色为目录f1,文件为t1) 常用选......