Java 中的 Semaphore(信号量)(java 信号量和锁的区别场景)
haoteby 2025-07-08 18:08 24 浏览
Semaphore 是 Java 并发包 ( java.util.concurrent ) 中的一个重要同步工具,用于控制对共享资源的并发访问线程数量。
基本概念
Semaphore(信号量)维护了一组许可证(permits),线程可以通过 Semaphore 来获取和释放许可证,从而控制对资源的访问。
核心特性
- 限制并发数:控制同时访问特定资源的线程数量
- 公平性选择:支持公平和非公平模式
- 可中断:支持可中断的获取操作
- 尝试获取:支持尝试获取和超时获取
基本用法
1. 创建 Semaphore
// 创建具有10个许可证的信号量(非公平模式)
Semaphore semaphore = new Semaphore(10);
// 创建具有10个许可证的信号量(公平模式)
Semaphore fairSemaphore = new Semaphore(10, true);
2. 获取许可证
// 获取一个许可证(阻塞直到获取到或线程被中断)
semaphore.acquire();
// 获取多个许可证
semaphore.acquire(3);
// 尝试获取许可证(非阻塞)
boolean acquired = semaphore.tryAcquire();
// 尝试获取许可证(带超时)
boolean acquired = semaphore.tryAcquire(1, TimeUnit.SECONDS);
3. 释放许可证
// 释放一个许可证
semaphore.release();
// 释放多个许可证
semaphore.release(3);
实际应用示例
1. 限制数据库连接池
public class ConnectionPool {
private final Semaphore semaphore;
private final List<Connection> connections;
public ConnectionPool(int poolSize) {
this.semaphore = new Semaphore(poolSize);
this.connections = Collections.synchronizedList(new ArrayList<>());
// 初始化连接池...
}
public Connection getConnection() throws InterruptedException {
semaphore.acquire();
return connections.remove(0);
}
public void releaseConnection(Connection conn) {
connections.add(conn);
semaphore.release();
}
}
2. 控制资源访问
// 限制同时只有5个线程可以访问某资源
Semaphore semaphore = new Semaphore(5);
void accessResource() throws InterruptedException {
semaphore.acquire();
try {
// 访问共享资源
} finally {
semaphore.release();
}
}
重要方法
方法 描述
acquire() 获取一个许可证,阻塞直到可用或线程被中断
acquire(int permits) 获取指定数量的许可证
acquireUninterruptibly() 不可中断地获取许可证
tryAcquire() 尝试获取许可证,立即返回成功或失败
tryAcquire(long timeout, TimeUnit unit) 尝试获取许可证,带超时
release() 释放一个许可证
release(int permits) 释放指定数量的许可证
availablePermits() 返回当前可用的许可证数量
drainPermits() 获取并返回所有立即可用的许可证
hasQueuedThreads() 查询是否有线程正在等待获取许可证
getQueueLength() 返回等待获取许可证的线程数
注意事项
- 许可证数量:创建时可以指定初始许可证数量,但实际数量可以超过初始值(通过 release() 增加)
- 公平性:公平模式下,线程按 FIFO 顺序获取许可证;非公平模式下可能插队
- 异常处理:acquire() 方法可能抛出 InterruptedException
- 释放次数:释放的许可证数量不必与获取的数量相同,但要小心不要过度释放
- 与锁的区别:Semaphore 可以允许多个线程访问,而锁通常只允许一个
底层实现
Semaphore 基于 AQS (
AbstractQueuedSynchronizer) 实现:
- 许可证数量对应 AQS 的状态值(state)
- 获取许可证相当于减少 state
- 释放许可证相当于增加 state
- 当 state ≤ 0 时,获取操作需要排队等待
Semaphore 是 Java 并发编程中非常有用的工具,特别适合资源池、限流等场景。
爱学习的小伙伴,更对精彩,关注不迷路哟~
相关推荐
- 一日一技:用Python程序将十进制转换为二进制
-
用Python程序将十进制转换为二进制通过将数字连续除以2并以相反顺序打印其余部分,将十进制数转换为二进制。在下面的程序中,我们将学习使用递归函数将十进制数转换为二进制数,代码如下:...
- 十进制转化成二进制你会吗?#数学思维
-
六年级奥赛起跑线:抽屉原理揭秘。同学们好,我是你们的奥耀老师。今天一起来学习奥赛起跑线第三讲二进制计数法。例一:把十进制五十三化成二进制数是多少?首先十进制就是满十进一,二进制就是满二进一。二进制每个...
- 二进制、十进制、八进制和十六进制,它们之间是如何转换的?
-
在学习进制时总会遇到多种进制转换的时候,学会它们之间的转换方法也是必须的,这里分享一下几种进制之间转换的方法,也分享两个好用的转换工具,使用它们能够大幅度的提升你的办公和学习效率,感兴趣的小伙伴记得点...
- c语言-2进制转10进制_c语言 二进制转十进制
-
#include<stdio.h>intmain(){charch;inta=0;...
- 二进制、八进制、十进制和十六进制数制转换
-
一、数制1、什么是数制数制是计数进位的简称。也就是由低位向高位进位计数的方法。2、常用数制计算机中常用的数制有二进制、八进制、十进制和十六进制。...
- 二进制、十进制、八进制、十六进制间的相互转换函数
-
二进制、十进制、八进制、十六进制间的相互转换函数1、输入任意一个十进制的整数,将其分别转换为二进制、八进制、十六进制。2、程序代码如下:#include<iostream>usingna...
- 二进制、八进制、十进制和十六进制等常用数制及其相互转换
-
从大学开始系统的接触计算机专业,到现在已经过去十几年了,今天整理一下基础的进制转换,希望给还在上高中的表妹一个入门的引导,早日熟悉这个行业。一、二进制、八进制、十进制和十六进制是如何定义的?二进制是B...
- 二进制如何转换成十进制?_二进制如何转换成十进制例子图解
-
随着社会的发展,电器维修由继电器时代逐渐被PLC,变频器,触摸屏等工控时代所替代,特别是plc编程,其数据逻辑往往涉及到数制二进制,那么二进制到底是什么呢?它和十进制又有什么区别和联系呢?下面和朋友们...
- 二进制与十进制的相互转换_二进制和十进制之间转换
-
很多同学在刚开始接触计算机语言的时候,都会了解计算机的世界里面大多都是二进制来表达现实世界的任何事物的。当然现实世界的事务有很多很多,就拿最简单的数字,我们经常看到的数字大多都是十进制的形式,例如:我...
- 十进制如何转换为二进制,二进制如何转换为十进制
-
用十进制除以2,除的断的,商用0表示;除不断的,商用1表示余0时结束假如十进制用X表示,用十进制除以2,即x/2除以2后为整数的(除的断的),商用0表示;除以2除不断的,商用1表示除完后的商0或1...
- 十进制数如何转换为二进制数_十进制数如何转换为二进制数举例说明
-
我们经常听到十进制数和二进制数,电脑中也经常使用二进制数来进行计算,但是很多人却不清楚十进制数和二进制数是怎样进行转换的,下面就来看看,十进制数转换为二进制数的方法。正整数转二进制...
- 二进制转化为十进制,你会做吗?一起来试试吧
-
今天孩子问把二进制表示的110101改写成十进制数怎么做呀?,“二进制”简单来说就是“满二进一”,只用0和1共两个数字表示,同理我们平常接触到的“十进制”是“满十进一”,只用0-9共十个数字表示。如果...
- Mac终于能正常打游戏了!苹果正逐渐淘汰Rosetta转译
-
Mac玩家苦转译久矣!WWDC2025苹果正式宣判Rosetta死刑,原生游戏时代终于杀到。Metal4光追和AI插帧技术直接掀桌,连Steam都连夜扛着ARM架构投诚了。看到《赛博朋克2077》...
- 怎么把视频的声音提出来转为音频?音频提取,11款工具实测搞定
-
想把视频里的声音单独保存为音频文件(MP3/AAC/WAV/FLAC)用于配音、播客、听课或二次剪辑?本文挑出10款常用工具,给出实测可复现的操作步骤、优缺点和场景推荐。1)转换猫mp3转换器(操作门...
- 6个mp4格式转换器测评:转换速度与质量并存!
-
MP4视频格式具有兼容性强、视频画质高清、文件体积较小、支持多种编码等特点,适用于网络媒体传播。如果大家想要将非MP4格式的视频转换成MP4的视频格式的话,可以使用MP4格式转换器更换格式。本文分别从...