呵,Semaphore ,就这?(一)

简介: 那么本篇文章我们继续来和你聊聊并发工具类的第二篇文章 --- Semaphore 。


认识 Semaphore

Semaphore 是什么

Semaphore 一般译作 信号量,它也是一种线程同步工具,主要用于多个线程对共享资源进行并行操作的一种工具类。它代表了一种许可的概念,是否允许多线程对同一资源进行操作的许可,使用 Semaphore 可以控制并发访问资源的线程个数。

Semaphore 的使用场景

Semaphore 的使用场景主要用于流量控制,比如数据库连接,同时使用的数据库连接会有数量限制,数据库连接不能超过一定的数量,当连接到达了限制数量后,后面的线程只能排队等前面的线程释放数据库连接后才能获得数据库连接。

再比如交通公路上的红绿灯,绿灯亮起时只能让 100 辆车通过,红灯亮起不允许车辆通过。

再比如停车场的场景中,一个停车场有有限数量的车位,同时能够容纳多少台车,车位满了之后只有等里面的车离开停车场外面的车才可以进入。

Semaphore 使用

下面我们就来模拟一下停车场的业务场景:在进入停车场之前会有一个提示牌,上面显示着停车位还有多少,当车位为 0 时,不能进入停车场,当车位不为 0 时,才会允许车辆进入停车场。所以停车场有几个关键因素:停车场车位的总容量,当一辆车进入时,停车场车位的总容量 - 1,当一辆车离开时,总容量 + 1,停车场车位不足时,车辆只能在停车场外等待。

public class CarParking {
    private static Semaphore semaphore = new Semaphore(10);
    public static void main(String[] args){
        for(int i = 0;i< 100;i++){
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("欢迎 " + Thread.currentThread().getName() + " 来到停车场");
                    // 判断是否允许停车
                    if(semaphore.availablePermits() == 0) {
                        System.out.println("车位不足,请耐心等待");
                    }
                    try {
                        // 尝试获取
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName() + " 进入停车场");
                        Thread.sleep(new Random().nextInt(10000));// 模拟车辆在停车场停留的时间
                        System.out.println(Thread.currentThread().getName() + " 驶出停车场");
                        semaphore.release();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, i + "号车");
            thread.start();
        }
    }
}

在上面这段代码中,我们给出了 Semaphore 的初始容量,也就是只有 10 个车位,我们用这 10 个车位来控制 100 辆车的流量,所以结果和我们预想的很相似,即大部分车都在等待状态。但是同时仍允许一些车驶入停车场,驶入停车场的车辆,就会 semaphore.acquire 占用一个车位,驶出停车场时,就会 semaphore.release 让出一个车位,让后面的车再次驶入。

Semaphore 信号量的模型

上面代码虽然比较简单,但是却能让我们了解到一个信号量模型的五脏六腑。下面是一个信号量的模型:

微信图片_20220418200146.png

来解释一下 Semaphore ,Semaphore 有一个初始容量,这个初始容量就是 Semaphore 所能够允许的信号量。在调用 Semaphore 中的 acquire 方法后,Semaphore 的容量 -1,相对的在调用 release 方法后,Semaphore 的容量 + 1,在这个过程中,计数器一直在监控 Semaphore 数量的变化,等到流量超过 Semaphore 的容量后,多余的流量就会放入等待队列中进行排队等待。等到 Semaphore 的容量允许后,方可重新进入。

Semaphore 所控制的流量其实就是一个个的线程,因为并发工具最主要的研究对象就是线程。

它的工作流程如下

微信图片_20220418200150.png

这幅图应该很好理解吧,这里就不再过多解释啦。

Semaphore 深入理解

在了解 Semaphore 的基本使用和 Semaphore 的模型后,下面我们还是得从源码来和你聊一聊 Semaphore 的种种细节问题,因为我写文章最核心的东西就是想让我的读者 了解 xxx,看这一篇就够了,这是我写文章的追求,好了话不多说,源码走起来!

Semaphore 基本属性

Semaphore 中只有一个属性

private final Sync sync;

Sync 是 Semaphore 的同步实现,Semaphore 保证线程安全性的方式和 ReentrantLock 、CountDownLatch 类似,都是继承于 AQS 的实现。同样的,这个 Sync 也是继承于 AbstractQueuedSynchronizer 的一个变量,也就是说,聊 Semaphore 也绕不开 AQS,所以说 AQS 真的太重要了。

            </div>
目录
相关文章
|
分布式计算 监控 网络协议
Hadoop集群长时间运行网络延迟原因
【6月更文挑战第20天】
352 2
|
存储 JavaScript 前端开发
盘点主流 Flutter 状态管理库2024
状态管理是每个应用不可缺少的,本文将会盘点下主流的状态管理包。
523 2
盘点主流 Flutter 状态管理库2024
|
5月前
|
传感器 算法 安全
《深度剖析分布式软总线:软时钟与时间同步机制探秘》
在分布式系统中,设备间的协同依赖精准的时间同步。软时钟与时间同步机制通过虚拟时钟和复杂算法,解决硬件时钟差异及网络延迟问题,确保多设备协调一致。其应用涵盖智能交通、工业自动化和金融交易等领域,为分布式系统的高效稳定运行提供核心支撑,助力未来智能世界发展。
134 8
|
11月前
|
Java
新版minio依赖对putObject进行了修改
本文介绍了MinIO客户端在新版中对`putObject`方法的修改,从旧版的直接传参到新版的链式调用构建器模式。
533 2
|
JavaScript Java 测试技术
基于SpringBoot+Vue个人博客系统设计和实现(源码+LW+部署讲解)
基于SpringBoot+Vue个人博客系统设计和实现(源码+LW+部署讲解)
178 7
|
存储 前端开发 JavaScript
44 个 React 前端面试问题
【8月更文挑战第18天】
175 2
|
Java 测试技术 数据安全/隐私保护
基于ssm+vue.js+uniapp小程序的医院门诊信息管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的医院门诊信息管理系统附带文章和源代码部署视频讲解等
94 0
基于ssm+vue.js+uniapp小程序的医院门诊信息管理系统附带文章和源代码部署视频讲解等
|
存储 Web App开发 移动开发
2023年最新前端面试题汇总大全(含答案超详细,HTML,JS,CSS汇总篇)-- 持续更新 2
2023年最新前端面试题汇总大全(含答案超详细,HTML,JS,CSS汇总篇)-- 持续更新
723 0
|
机器学习/深度学习 数据可视化 TensorFlow
TensorFlow 实战(七)(2)
TensorFlow 实战(七)
148 0

热门文章

最新文章