Semaphore(信号量)介绍以及实例

简介: Semaphore(信号量)介绍以及实例

一、介绍


Semaphore是 java.util.Concurrent下的一个类

image.png

Semaphore翻译过来是信号量的意思,它的作用是控制多个线程对同一个资源的访问线程数量。比如在停车场停车,里面有10个车位,当这10个车位被停满的时候其他的车只能等待(堵塞)里面有车驶出(release)然后再进入。

Semaphore可以用做流量控制,主要是共用资源的应用场景。

二、常用方法


void acquire()从该信号量获取许可证,阻止直到可用,或线程为 interrupted
void acquire(int permits)从该信号量获取给定数量的许可证,阻止直到所有可用,否则线程为 interrupted
void acquireUninterruptibly()从这个信号灯获取许可证,阻止一个可用的。
void acquireUninterruptibly(int permits)从该信号量获取给定数量的许可证,阻止直到所有可用。
int availablePermits()返回此信号量中当前可用的许可数。
void release()释放许可证,将其返回到信号量。
void release(int permits)释放给定数量的许可证,将其返回到信号量。
boolean tryAcquire()从这个信号量获得许可证,只有在调用时可以使用该许可证。
boolean tryAcquire(int permits)从这个信号量获取给定数量的许可证,只有在调用时全部可用。
  • acquire():获取一个访问令牌,获取令牌就可以对资源进行访问,如果没有获取成功就阻塞等待。
  • release():在获取玩资源时归还令牌,给其他的线程使用。
  • tryacquire():获取一个访问令牌,获取令牌就可以对资源进行访问,如果没有获取成功不阻塞等待而是返回一个false。
  • availablePermits():获取许可证的总数

三、Semaphore的构造


image.png

传入一个permits来表示当前信号量允许拥有的最大许可数量。

四、实例


public class SemaphoreDemo {
    public static int num = 0;
    public static void main(String[] args) throws InterruptedException {
        Semaphore semaphore = new Semaphore(1);
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    for (int j = 0; j < 5000; j++) {
                        num++;
                    }
                    semaphore.release();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        }
        Thread.sleep(3000);
        System.out.println(num);
    }
}

image.png

这里我创建了两个匿名线程分别去执行5000次对num的++操作,这里的运行结果时10000而没有出现线程竞争出现的加数原子性问题,是因为这里我限制了许可证只有一个当一个线程拿到并且在执行完后才能归还许可让下一个阻塞等待的线程拿到去执行。

最后的Thread.sleep(300)是让主线程等待一下我们创建的两个线程执行完再输出num的值。

如果有多线程的问题可以访问我的博客主页欢迎讨论!

相关文章
|
安全
选择最佳供应商:ERP系统的供应商选择与评估方法论
选择最佳供应商:ERP系统的供应商选择与评估方法论
1542 0
|
SQL 存储 druid
Minerva -- Airbnb 的大规模数据指标系统 Part 3
Minerva -- Airbnb 的大规模数据指标系统 Part 3
734 0
Minerva -- Airbnb 的大规模数据指标系统 Part 3
|
8月前
|
云安全 边缘计算 监控
R9-9950X服务器 超越频率桎梏,企业级稳定性的新标杆!
德迅云安全推出的R9 9950X服务器专为多线程、高负载场景优化,基于AMD Ryzen 9系列的Zen 4架构,采用5nm工艺和CCD/CIOD分离设计,具备16核32线程全大核策略,确保高效能与低功耗。其自适应功耗管理和强化供电设计,保障了在企业级应用中的卓越稳定性和持续性能。搭配德迅卫士主机安全软件,提供实时监控、远程防护及资产清点等全面安全措施,适用于云计算、虚拟化和边缘计算等场景,为企业带来可靠的高性能解决方案。
|
JSON 前端开发 JavaScript
【JavaScript技术专栏】JavaScript异步编程:Promise、async/await解析
【4月更文挑战第30天】JavaScript中的异步编程通过Promise和async/await来解决回调地狱问题。Promise代表可能完成或拒绝的异步操作,有pending、fulfilled和rejected三种状态。它支持链式调用和Promise.all()、Promise.race()等方法。async/await是ES8引入的语法糖,允许异步代码以同步风格编写,提高可读性和可维护性。两者结合使用能更高效地处理非阻塞操作。
270 0
|
NoSQL Shell MongoDB
Mac OSX 平台安装 MongoDB
10月更文挑战第11天
244 4
|
机器学习/深度学习 人工智能 数据挖掘
Numba是一个Python库,用于对Python代码进行即时(JIT)编译,以便在硬件上高效执行。
Numba是一个Python库,用于对Python代码进行即时(JIT)编译,以便在硬件上高效执行。
|
JavaScript 前端开发 API
尤雨溪分享 Vue.js 10 年的发展历程,谈谈我看完后的启发和感受!!
尤雨溪分享 Vue.js 10 年的发展历程,谈谈我看完后的启发和感受!!
|
XML 数据格式
XML如何添加注释?
注释以  结束,例如 。注释可以出现在文档序言中,包括文档类型定义 (DTD);文档之后;或文本内容中。 注释不能出现在属性值中。 不能出现在标记中。分析器在遇到 > 时,就认为注释已结束;然后继续将文档作为正常的 XML 处理。
2731 0
|
Prometheus 监控 数据可视化
配置grafana的具体情况
配置grafana的具体情况
196 2