热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java多线程aqs实现工具类_Java多线程并发工具类信号量Semaphore对象讲解

Java多线程并发工具类-Semaphore对象讲解通过前面的学习,我们已经知道了Java多线程并发场景中使用比较多的两个工具类:做加法的CycliBa

Java多线程并发工具类-Semaphore对象讲解

通过前面的学习,我们已经知道了Java多线程并发场景中使用比较多的两个工具类:做加法的CycliBarrier对象以及做减法的CountDownLatch对象并对这两个对象进行了比较。我们发现这两个对象要么是做加法,要么是做减法的。那么有没有既做加法也做减法的呢?当然有了。Semaphore这个工具类就可以实现One out one in的。

本文主要内容:Semaphore是什么?从生活中例子中来理解Semaphore;代码演示;总结。通过总结-理解-代码演示-再总结这四个步骤让大家来深刻的理解。

本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《并发工具类》教程的第三篇:《Java多线程下信号量》。

一:Semaphore是什么?

Semaphore中文意思:信号量。

来看看JavaAPI中对semaphore对象的解释:

bb993f3889970875fe3c59bd6b6bc68a.png

什么意思呢?

简单理解来说,Semaphore:信号量主要用于两个目的:一个是用于多个共享资源的互斥使用;另一个用于并发线程数量的控制。什么意思呢?我们来从生活中的例子来理解。

二:从生活中例子中来理解Semaphore

案例一:抢车位

自驾游的朋友一般都会遇到这样的烦恼:去景区游玩,停车比较麻烦。因为停车场中的车位数量是一定的。当车位满了以后,其他想要进入停车场停车的车辆只能等待。等到其他车辆出来之后,才可以进入。站在并发角度来分析的话:停车场有多个停车位(多个共享资源),每个车辆只能停在其中一个位置上(互斥使用的),停车场的停车位是固定的(并发线程数量的控制)。这样是不是就好理解了?如果还是不好理解,接着看下面这个案例

案例二:海底捞吃火锅

去海底捞吃火锅的时候,海底捞场地就餐桌数量是固定的,假设有5桌。现在来了8个人,那么其他3个就需要在门口候餐区等待加号。当有其他桌吃完离开之后,进去一个。简图如下:

三:代码演示

我们就来模拟海底捞吃火锅的场景。

216573260cf54333fd0d7d5353d58d17.png

3.1:为什么要使用Semaphore?

为什么不能使用其他两个同步工具类呢?

根据CountDownLatch的特性,只能使用一次的特征来说,海底捞这种场景当然不能够使用了。因为开个店不可能只使用一次。

CyclicBarrier,虽然可以使用多次,但是需要reset之后才可以多次使用。意思就是,只有等餐厅里面5个桌的客人都吃完之后,才可以让其他人进来就餐的。这种情况也是不符合业务逻辑的。

而Semaphore可以做到One out One in 很适合海底捞的场景。所以,经过分析,我们可以得到如下代码。

代码演示:

餐桌对象:

2819dd09f7f835729493a35de52d4baa.png

执行方法:

7e5c6d71c03dbdccf1e3cfd92806cae7.png

运行结果:

f092c7df4564e2ad928480ab4a859083.png

从运行结果中,我们可以看到一个进入一个就离开,一个离开餐桌下一位就进入餐厅就餐。达到我们预期结果了。

四:总结

4.1:使用语法

在声明smaphore的时候需要设置线程数量。然后使用acquire获取资源。在finally方法里面调用release方法进行释放资源。如下图:

b9ab0e0e38083c61b0376712cbbe73b3.png

4.2:内部主要组成

4.2.1:三个内部类:

8cbaab5c3dd7300501cad18f320eb085.png

看到这三个类是不是很熟悉?对就是我们前面介绍的ReentrantLock和ReentrantReadWriteLock这两个对象里面都存在的。继承AQS的Sync类以及公平锁的FairSync类和非公平锁的NonfairSync类。同样,semaphore也支持在构造器中指定是公平还是非公平的:

43a28d3c4e541102fe6e418c918afa26.png

4.2.2:主要方法

重要的方法获取和释放方法:

获取资源的:

acquire()/acquire(int permits):获取资源(许可证)/获取指定个数的资源

释放资源:

release()/release(int permits):释放资源/释放指定个数的资源

其他方法:

阻止获取资源:

acquireUninterruptibly()/acquireUninterruptibly(int permits):从这个信号灯获取许可证,阻止一个可用的/阻止指定数量的

获取当前可以用的资源数量: int availablePermits()

还有其他很多方法。凯哥这里就不一一介绍了。大家可以自行查看API

4.3:实现原理

看到Sync这个内部类之后,大家就应该想到了凯哥(kaigejava)在之前介绍过的AQS对象了。没错,Semaphore就是使用AQS和CAS来实现资源的获取和释放的。在这里凯哥就不赘述了。大家可以看看前面凯哥介绍并发容器的同步器相关文章,里面凯哥做了详细的介绍。

wx.jpg

​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​    ​                                                ​欢迎来聊~



推荐阅读
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 云原生应用最佳开发实践之十二原则(12factor)
    目录简介一、基准代码二、依赖三、配置四、后端配置五、构建、发布、运行六、进程七、端口绑定八、并发九、易处理十、开发与线上环境等价十一、日志十二、进程管理当 ... [详细]
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
author-avatar
我确实是一只猪_143_267
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有