`

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

阅读更多

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

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

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

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

一:Semaphore是什么?

Semaphore中文意思:信号量。

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

 

什么意思呢?

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

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

案例一:抢车位

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

案例二:海底捞吃火锅

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

三:代码演示

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

 

3.1:为什么要使用Semaphore?

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

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

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

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

代码演示:

餐桌对象:

 

执行方法:

 

运行结果:

 

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

四:总结

4.1:使用语法

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

 

4.2:内部主要组成

4.2.1:三个内部类:

 

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

 

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来实现资源的获取和释放的。在这里凯哥就不赘述了。大家可以看看前面凯哥介绍并发容器的同步器相关文章,里面凯哥做了详细的介绍。

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

0
3
分享到:
评论

相关推荐

    vc++ multithread多线程教程---线程通信--利用事件对象,线程同步--使用信号量,线程同步--使用互斥量,线程同步--使用临界区

    本教程将深入探讨四种常见的线程同步机制:事件对象、信号量、互斥量以及临界区,帮助开发者理解和掌握如何在VC++中安全地实现多线程通信。 一、事件对象 事件对象是Windows API中用于线程间通信的一种同步机制。它...

    Java多线程编程实战指南-核心篇

    Java提供了多种同步工具,如synchronized关键字、wait()和notify()方法、Lock接口(包括ReentrantLock可重入锁)以及Semaphore信号量等。这些工具能够确保共享资源在多线程访问时的安全性,防止数据竞争和死锁的发生...

    Java 模拟线程并发

    最后,Java并发库还包含了很多其他有用的工具,如Semaphore(信号量)用于控制同时访问特定资源的线程数量,CyclicBarrier(循环屏障)和CountDownLatch(计数器门锁)用于多线程间的协作,以及Lock接口及其实现如...

    使用信号量(Semaphore)实现线程的同步

    信号量(Semaphore)是操作系统中一种重要的同步机制,它用于管理多个线程对共享资源的访问,以防止并发执行时产生竞态条件。在多线程编程中,当多个线程试图同时访问一个有限的资源时,信号量可以帮助我们协调这些...

    Java多线程之并发工具类

    Java并发工具类是Java多线程编程中必不可少的一部分,它们为开发者提供了更加高效和灵活的线程同步机制。本文将详细介绍三个重要的并发工具类:CountDownLatch、CyclicBarrier和Semaphore。 首先,CountDownLatch是...

    Java并发编程(23)并发新特性-信号量Semaphor

    信号量(Semaphore)是Java并发库中的一种工具类,它提供了一种控制多个线程对共享资源访问的方式,从而实现高级别的同步。在Java 5引入并发包`java.util.concurrent`后,信号量作为`Semaphore`类被添加,成为并发...

    java多线程并发实战和源码

    总结来说,Java多线程并发实战和源码的学习涵盖了线程创建与管理、同步机制、并发容器、内存模型以及并发工具类等多个方面。虽然书中实例不足,但通过结合其他资源,如jcip-examples-src.rar中的代码,可以进一步...

    Java多线程实战精讲-带你一次搞明白Java多线程高并发

    9. **并发工具类** - **CountDownLatch**:用于计数,当计数值为零时,所有等待的线程可以继续执行。 - **CyclicBarrier**:多线程同步点,允许一组线程等待其他线程到达某个点后再继续执行。 - **Semaphore**:...

    java并发工具类(CountDownLatch+Semaphore+Exchanger)

    Java并发工具类是Java并发编程中的重要组成部分,其中包括了多种实用的工具,如CountDownLatch、Semaphore和Exchanger,这些工具类极大地简化了多线程环境下的同步和协调问题。 1. **CountDownLatch**: ...

    java并发之并发工具类

    Java 并发工具类中有很多种,今天我们主要介绍四种:CyclicBarrier、CountDownLatch、Semaphore 和 Exchanger。 一、CyclicBarrier CyclicBarrier 是一种同步工具,允许一组线程互相等待,直到到达某个公共屏障点...

    JAVA 多线程之信号量(Semaphore)实例详解

    在Java多线程编程中,信号量Semaphore是一种非常重要的同步工具,用于控制对公共资源的访问。Semaphore类位于`java.util.concurrent`包下,它允许我们限制同时访问特定资源的线程数量。 ### Semaphore简介 信号量...

    Java 多线程与并发(2-26)Java 并发 - 线程基础.pdf

    Java多线程与并发是Java编程中至关重要的一个领域,特别是在构建高性能、高并发的应用时。线程基础是理解并发编程的关键,它涉及到线程的状态转换、创建与使用方式、同步与协作机制等方面。 线程有五种基本状态: 1...

    多线程精品资源--这是RedSpider社区成员原创与维护的Java多线程系列文章。.zip

    7. **并发工具类** - **CountDownLatch、CyclicBarrier、Semaphore**:这些工具类可以帮助我们构造复杂的并发场景,如计数器、栅栏和信号量。 8. **并发编程的最佳实践** - **避免全局锁**:尽量减少使用全局锁,...

    Java多线程并发访问解决方案

    在Java编程中,多线程并发访问是提升应用程序性能的重要手段,但同时也带来了数据一致性、安全性及效率等问题。本文将深入探讨Java中的多线程并发访问解决方案,主要围绕以下几个核心知识点进行阐述: 1. **线程...

    JAVA线程高级-线程按序交替执行

    Java提供了一些高级特性来实现这样的需求,比如`Thread`类、`synchronized`关键字以及Java并发工具包(JUC, Java Util Concurrency)中的类。 1. **线程的生命周期与状态**: - 线程有新建、就绪、运行、阻塞和死亡...

    汪文君JAVA多线程编程实战(完整不加密)

    本书还涉及到了Java并发工具类,如Semaphore信号量、CyclicBarrier栅栏、CountDownLatch倒计时器等,这些都是Java并发编程中的重要工具,可以帮助开发者更精细地控制线程执行。另外,书中还会介绍如何使用Future和...

    多线程,高并发.zip

    Java提供了多种同步工具,如`synchronized`关键字、`Lock`接口(如`ReentrantLock`)、`Semaphore`信号量、`CountDownLatch`计数器和`CyclicBarrier`回环栅栏。这些工具用于控制线程间的访问顺序,防止数据竞争,...

    c++多线程同步——信号量

    信号量(Semaphore)是实现多线程同步的一种有效工具,常用于控制对共享资源的访问。在这个名为"Mthread11"的MFC工程中,我们可以看到如何在C++环境中应用信号量来解决多线程间的同步问题。 首先,我们需要理解什么...

    java多线程并发编程例子

    Java多线程并发编程是Java开发中的重要领域,特别是在服务器端和高并发应用中不可或缺。`java.util.concurrent`包提供了丰富的工具类,帮助开发者更好地管理线程和优化并发性能。以下将详细介绍标题和描述中涉及的...

    Java多线程运算集合

    - Java提供了多种同步机制来解决多线程并发访问同一资源时可能出现的问题,如同步方法、同步块等。 - 同步方法通过 `synchronized` 关键字修饰类的方法,同步块则通过对特定对象加锁实现。 - **锁机制**: - 锁...

Global site tag (gtag.js) - Google Analytics