首页 > 其他分享 >并发工具类

并发工具类

时间:2024-07-17 10:56:54浏览次数:14  
标签:获取 Semaphore 并发 state 线程 CountDownLatch 工具 CyclicBarrier

文章目录

Java 的并发工具类提供了一系列方便实用的方法,用于简化多线程编程。以下是一些常见的并发工具类:

  • Semaphore:实现信号量,控制资源的访问。
  • CountDownLatch:用于等待一组线程完成。
  • CyclicBarrier:让一组线程等待彼此到达某个同步点。

一、Semaphore

1.1 作用

synchronizedReentrantLock 都是一次只允许一个线程访问某个资源,而Semaphore(信号量)可以用来控制同时访问特定资源的线程数量。Semaphore 的使用简单,我们这里假设有 N(N>5) 个线程来获取 Semaphore 中的共享资源,下面的代码表示同一时刻 N 个线程中只有 5 个线程能获取到共享资源,其他线程都会阻塞,只有获取到共享资源的线程才能执行。等到有线程释放了共享资源,其他阻塞的线程才能获取到。

// 初始共享资源数量
final Semaphore semaphore = new Semaphore(5);
// 获取1个许可
semaphore.acquire();
// 释放1个许可
semaphore.release();

当初始的资源个数为 1 的时候,Semaphore 退化为排他锁。
Semaphore 有两种模式:

  • 公平模式: 调用 acquire() 方法的顺序就是获取许可证的顺序,遵循 FIFO
  • 非公平模式: 抢占式的

Semaphore 对应的两个构造方法如下:

public Semaphore(int permits) {
    sync = new NonfairSync(permits);
}

public Semaphore(int permits, boolean fair) {
    sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}

这两个构造方法,都必须提供许可的数量,第二个构造方法可以指定是公平模式还是非公平模式,默认非公平模式Semaphore 通常用于那些资源有明确访问数量限制的场景比如限流

1.2 Semaphore 的原理

Semaphore共享锁的一种实现,它默认构造 AQSstate 值为 permits,你可以将 permits 的值理解为许可证的数量,只有拿到许可证的线程才能执行。调用semaphore.acquire() ,线程尝试获取许可证,如果 state >= 0 的话,则表示可以获取成功。如果获取成功的话,使用 CAS 操作去修改 state 的值 state=state-1。如果 state<0 的话,则表示许可证数量不足。此时会创建一个 Node 节点加入阻塞队列,挂起当前线程。

不了解AQS和CAS机制的话建议阅读下面两篇文章:
AQS详解
CAS详解

/**
 *  获取1个许可证
 */
public void acquire() throws InterruptedException {
    sync.acquireSharedInterruptibly(1);
}
/**
 * 共享模式下获取许可证,获取成功则返回,失败则加入阻塞队列,挂起线程
 */
public final void acquireSharedInterruptibly(int arg)
    throws InterruptedException {
    if (Thread.interrupted())
      throw new InterruptedException();
        // 尝试获取许可证,arg为获取许可证个数,当可用许可证数减当前获取的许可证数结果小于0,则创建一个节点加入阻塞队列,挂起当前线程。
    if (tryAcquireShared(arg) < 0)
      doAcquireSharedInterruptibly(arg);
}

调用semaphore.release(); ,线程尝试释放许可证,并使用 CAS 操作去修改 state 的值 state=state+1。释放许可证成功之后,同时会唤醒同步队列中的一个线程。被唤醒的线程会重新尝试去修改 state 的值 state=state-1 ,如果 state>=0 则获取令牌成功,否则重新进入阻塞队列,挂起线程。

// 释放一个许可证
public void release() {
    sync.releaseShared(1);
}

// 释放共享锁,同时会唤醒同步队列中的一个线程。
public final boolean releaseShared(int arg) {
    //释放共享锁
    if (tryReleaseShared(arg)) {
      //唤醒同步队列中的一个线程
      doReleaseShared();
      return true;
    }
    return false;
}

二、CountDownLatch

2.1 作用

CountDownLatch 允许count 个线程阻塞在一个地方,直至所有线程的任务都执行完毕。CountDownLatch 是一次性的,计数器的值只能在构造方法中初始化一次,之后没有任何机制再次对其设置值,当 CountDownLatch 使用完毕后,它不能再次被使用。

2.2 CountDownLatch 的原理

CountDownLatch 是共享锁的一种实现,它默认构造 AQSstate 值为 count。当线程使用 countDown() 方法时,其实使用了tryReleaseShared方法以 CAS 的操作来减少 state,直至 state 为 0 。当调用 await() 方法的时候,如果 state 不为 0,那就证明任务还没有执行完毕,await() 方法就会一直阻塞,也就是说 await() 方法之后的语句不会被执行。直到count 个线程调用了countDown()使 state 值被减为 0,或者调用await()的线程被中断,该线程才会从阻塞中被唤醒,await() 方法之后的语句得到执行。

2.3 使用场景

CountDownLatch 的作用就是 允许 count 个线程阻塞在一个地方,直至所有线程的任务都执行完毕。在公司的一个使用线程池做数据导出的业务中就用到CountDownLatch阻塞多条线程的任务,等待所有任务执行完成后才会接着执行后面的逻辑

项目场景二:使用线程池+分页查询大数据并导出

三、CyclicBarrier

3.1 作用

CyclicBarrierCountDownLatch 非常类似,它也可以实现线程间的技术等待,但是它的功能比 CountDownLatch 更加复杂和强大。主要应用场景和 CountDownLatch 类似。CountDownLatch 的实现是基于 AQS 的,而 CycliBarrier 是基于 ReentrantLock(ReentrantLock 也属于 AQS 同步器)和 Condition 的。CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是:让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。

3.2 CyclicBarrier 的原理

CyclicBarrier 内部通过一个 count 变量作为计数器,count 的初始值为 parties 属性的初始化值,每当一个线程到了栅栏这里了,那么就将计数器减 1。如果 count值为 0 了,表示这是这一代最后一个线程到达栅栏,就尝试执行我们构造方法中输入的任务。

//每次拦截的线程数
private final int parties;
//计数器
private int count;

下面我们结合源码来简单看看。
1、CyclicBarrier默认的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用 await() 方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。

public CyclicBarrier(int parties) {
    this(parties, null);
}

public CyclicBarrier(int parties, Runnable barrierAction) {
    if (parties <= 0) throw new IllegalArgumentException();
    this.parties = parties;
    this.count = parties;
    this.barrierCommand = barrierAction;
}

其中,parties 就代表了有拦截的线程的数量,当拦截的线程数量达到这个值的时候就打开栅栏,让所有线程通过。
2、当调用 CyclicBarrier 对象调用 await() 方法时,实际上调用的是 dowait(false, 0L)方法。await()方法就像树立起一个栅栏的行为一样,将线程挡住了,当拦住的线程数量达到 parties 的值时,栅栏才会打开,线程才得以通过执行。

标签:获取,Semaphore,并发,state,线程,CountDownLatch,工具,CyclicBarrier
From: https://blog.csdn.net/SRY12240419/article/details/140484996

相关文章

  • MarkText A simple and elegant markdown editor, available for Linux, macOS and Wi
    1、这个工具挺不错的,先上一张图,来自github页面截图:2、这个工具是开源的项目,开源地址:https://github.com/marktext官网地址:www.marktext.cc/三个平台都有:可以直接点上面的按钮,找到自己所用电脑的平台,就可以下载。也可以转到Githubreleasepage下载。3、安装:点击【安......
  • 我日常是如何使用LLM工具的:你的LLM工具没用起来,可能是因为方法不对。
    引言我对Prompt认知经历了2个阶段:第一阶段:去年3月-11月,我认为Prompt最终会灭亡。第二阶段:去年12月至今,我有两个理解:在主流LLM工具(比如ChatGPT,文心一言等大模型厂商的对话产品,以下统称LLM工具)中,Prompt能力未来会像我们现在使用word,ppt,excel的能力......
  • java中用高德工具测试两点的距离
    文章讲述了如何在Java中利用DistinctUtil工具类通过高德地图API获取两个地理位置之间的驾车距离,涉及经纬度处理、URL构建、HTTP请求和JSON解析过程。摘要由CSDN通过智能技术生成  代码如下:StringstartLongitude=entity.getLONGITUDE();//起点(当前位置)经度......
  • DBeaver安装教程(开发人员和数据库管理员通用数据库管理工具)
    前言DBeaver是一个通用的数据库管理工具和SQL客户端,支持MySQL,PostgreSQL,Oracle,DB2,MSSQL,Sybase,Mimer,HSQLDB,Derby,以及其他兼容JDBC的数据库。DBeaver提供一个图形界面用来查看数据库结构、执行SQL查询和脚本,浏览和导出数据,处理BLOB/CLOB数据,修改数据库结......
  • 【敏捷开发方法论】敏捷开发流程和工具实践
    敏捷开发方法论敏捷开发流程和工具实践目录敏捷开发简介敏捷开发的核心价值观和原则敏捷开发流程常见的敏捷开发框架敏捷开发工具敏捷开发的最佳实践实施敏捷开发的挑战及解决方案成功案例分析1.敏捷开发简介什么是敏捷开发敏捷开发是一种强调灵活性和响应性的现代......
  • LocalSend v1.15.0:一款免费的跨平台局域网文件传输工具
    今天电脑天空向大家介绍一款实用的开源跨平台局域网文件传输工具——LocalSendv1.15.0。这款工具能够帮助我们在不同的操作系统之间快速、安全地传输文件,非常适合开发者和IT专业人员使用。以下是LocalSend的详细介绍和使用指南。工具简介LocalSend是一款基于Web技术的文件......
  • 硬件检测工具 | CPU-Z v2.10.0 官方中文绿色版
    软件简介CPU-Z是一款广受欢迎的硬件检测工具,主要用于收集电脑处理器的详细信息。这款软件能够提供关于CPU的详细数据,包括处理器名称、编号、代号、进程和缓存等信息。此外,CPU-Z还能实时监测每个内核的内部频率和内存频率,以及收集主板和芯片组、内存类型、大小和时序等信息。......
  • Springboot定义阿里云oss工具类
    Springboot定义阿里云oss工具类文章目录Springboot定义阿里云oss工具类1、定义OSS相关配置2、读取OSS配置3、生成OSS工具类对象4、定义使用工具类1、定义OSS相关配置首先,在application.yml文件中定义阿里云OSS的相关配置信息。这些配置包括endpoint、acces......
  • 数据仓库建模工具之一——Hive学习第二天
    Hive的概述1、Hive基本概念1.1 Hive简介Hive本质是将SQL转换为MapReduce的任务进行运算,底层由HDFS来提供数据存储,说白了hive可以理解为一个将SQL转换为MapReduce的任务的工具,甚至更近一步说hive就是一个MapReduce客户端。为什么使用Hive?使用hadoop,成本太高,项目要求周期太......
  • 免费的可视化工具哪里找?看过来!
    面对海量的数据,我们应该如何高效地提取其价值,让复杂的信息一目了然?这正是可视化工具大显身手的舞台。今天,我就来分享几款非常好用的数据可视化工具,它们不仅能够帮助你轻松驾驭数据,还能让你的工作汇报、项目展示更加生动、专业。 一、山海鲸可视化 二维项目制作和私有化部署......