0

0

在Java中Semaphore如何控制并发访问_Java信号量同步机制说明

P粉602998670

P粉602998670

发布时间:2026-02-11 09:49:02

|

705人浏览过

|

来源于php中文网

原创

Semaphore许可数应根据目标资源真实容量设定,如数据库连接池为5则设为5,需预留10%~20%余量,动态资源应换用Resilience4j等限流器。

在java中semaphore如何控制并发访问_java信号量同步机制说明

Semaphore 初始化时 permits 数设多少才合理

信号量的许可数不是随便填的,它直接决定最多几个线程能同时进入临界区。设得太小,吞吐上不去;设太大,起不到限流作用,甚至可能压垮下游资源。

常见误判是照搬线程池大小(比如 Executors.newFixedThreadPool(10) 就配 new Semaphore(10)),但这两者语义不同:线程池控制的是“执行者数量”,而 Semaphore 控制的是“持有某类资源的并发数”。比如数据库连接池只有 5 个连接,那 Semaphore 就该设为 5,哪怕你开了 20 个线程。

  • 查清目标资源的真实容量(如 Redis 连接数、HTTP 客户端最大连接、文件句柄上限)
  • 考虑突发流量,可预留 10%~20% 余量,但别盲目放大
  • 如果资源是动态伸缩的(如云数据库连接池自动扩缩),Semaphore 就不适合——得换用更灵活的限流器(如 Resilience4j RateLimiter

acquire() 和 tryAcquire() 的关键区别在哪

这两个方法看着像,但阻塞行为和错误处理逻辑完全不同,选错会导致线程卡死或请求无声失败。

acquire() 会一直阻塞直到拿到许可,除非被中断;而 tryAcquire() 立即返回 boolean,拿不到就走 else 分支——这才是做超时/降级的正确姿势。

立即学习Java免费学习笔记(深入)”;

  • 不要在定时任务或响应敏感服务里用 acquire(),没设超时等于埋雷
  • 要用带超时的版本:tryAcquire(long timeout, TimeUnit unit),超时后必须显式处理失败逻辑(如返回 429、走缓存、抛业务异常)
  • acquireUninterruptibly() 更危险:连 Thread.interrupt() 都无法打断,JVM 停机时可能 hang 住

释放许可时忘记调用 release() 会怎样

这是最隐蔽也最致命的问题:不 release,许可数永远不归还,后续所有线程都在 acquire() 上阻塞,应用逐渐假死。

vizcom.ai
vizcom.ai

AI草图渲染工具,快速将手绘草图渲染成精美的图像

下载

根本原因不是语法错误,而是控制流分支遗漏——比如异常路径、return 提前退出、或者用了 try-with-resources 却没把 Semaphore 包进去(它不实现 AutoCloseable)。

  • 必须把 release() 放在 finally 块里,哪怕只有一行代码也要包住
  • 别信“我这段逻辑肯定不会异常”,网络 IO、NPE、OOM 都可能发生在 acquire 之后、release 之前
  • 可以封装工具方法,例如 withPermit(sem, () -> { /* do work */ }),内部确保 release

公平模式(fair = true)真的有必要开吗

默认非公平,新线程可能插队抢到刚释放的许可;设成公平后,按等待顺序分发,但性能下降 10%~30%,且不能完全避免饥饿(比如持续高并发下,后面排队的线程可能永远等不到)。

绝大多数场景不需要开公平模式。它只在极少数业务语义强制要求“先到先得”时才有意义,比如订单号生成、库存扣减这种对顺序敏感的操作。

  • Web 请求、日志写入、缓存更新——这些都不需要公平,吞吐优先
  • 开启后记得压测对比 QPS 和 P99 延迟,别凭感觉
  • 即使开了公平,也不能替代分布式锁;多 JVM 实例间仍需外部协调(如 Redis + Lua)

实际用的时候,最常出问题的不是怎么写,而是没想清楚「这个信号量到底在保护什么资源」。一上来就 new Semaphore(10),结果发现 10 是数据库连接数,但业务里还有 3 个线程在同时读文件、2 个在调第三方 API——全挤在同一个信号量下,反而造成无关操作互相阻塞。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

382

2023.08.11

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

242

2023.10.07

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

356

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.30

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

633

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

91

2025.12.01

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

990

2023.11.02

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

655

2023.11.14

Rust异步编程与Tokio运行时实战
Rust异步编程与Tokio运行时实战

本专题聚焦 Rust 语言的异步编程模型,深入讲解 async/await 机制与 Tokio 运行时的核心原理。内容包括异步任务调度、Future 执行模型、并发安全、网络 IO 编程以及高并发场景下的性能优化。通过实战示例,帮助开发者使用 Rust 构建高性能、低延迟的后端服务与网络应用。

1

2026.02.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.4万人学习

C# 教程
C# 教程

共94课时 | 9.1万人学习

Java 教程
Java 教程

共578课时 | 63.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号