news 2026/3/31 19:46:13

Java面试必看!Semaphore的作用及实战案例解析!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java面试必看!Semaphore的作用及实战案例解析!

文章目录

  • Java面试必看!Semaphore的作用及实战案例解析!
    • 引言
    • 一、Semaphore的基本概念
      • 1.1 什么是Semaphore?
      • 1.2 Semaphore的工作原理
    • 二、Semaphore的核心方法
      • 2.1 acquire() 方法
      • 2.2 release() 方法
      • 2.3 getQueueLength() 方法
      • 2.4 availablePermits() 方法
    • 三、Semaphore的应用场景
      • 3.1 控制并发数
      • 3.2 替代ReentrantLock
      • 3.3 实现信号量机制
    • 四、总结
    • 希望本文能够帮助大家更好地理解和使用Java中的`Semaphore`!
      • 📚 领取 | 1000+ 套高质量面试题大合集(无套路,闫工带你飞一把)!

Java面试必看!Semaphore的作用及实战案例解析!

引言

各位小伙伴们,大家好啊!闫工又来给大家讲解Java面试中的知识点啦!今天咱们要聊的是一个非常重要的同步工具——** Semaphore(信号量)**。这可是Java多线程编程中不可或缺的一部分,掌握它不仅能让你在面试中脱颖而出,还能在实际开发中游刃有余。

相信很多小伙伴都听说过Semaphore这个词,但可能对它的具体作用和使用场景还不是很清楚。没关系,今天闫工就带着大家一起深入了解 Semaphore 的前世今生,从理论到实战,手把手教大家如何玩转这个强大的工具!

一、Semaphore的基本概念

1.1 什么是Semaphore?

Semaphore(信号量)是Java中用于控制同时访问特定资源的线程数量的一种同步工具。它就像一个交通警察,负责协调多个线程对共享资源的访问,确保系统的稳定性和高效性。

在多线程编程中,我们经常需要限制某些资源的并发访问数,比如数据库连接池、文件读写操作等。Semaphore就可以很好地解决这个问题,它可以控制同时访问这些资源的线程数量,从而避免资源被过度使用或者发生竞争。

1.2 Semaphore的工作原理

Semaphore的核心思想是基于许可(permits)机制。每个信号量都有一个固定的许可数量,当线程想要访问受控资源时,必须先获取一个许可;如果所有许可都被占用,那么该线程就会被阻塞,直到有其他线程释放许可。

举个简单的例子:假设我们有一个Semaphore对象,初始化时设置为3。这意味着最多允许3个线程同时访问某个资源。当第4个线程试图访问这个资源时,它会被阻塞,直到其中一个线程释放许可为止。

二、Semaphore的核心方法

在Java中,Semaphore类位于java.util.concurrent包下,提供了以下几个核心方法:

2.1 acquire() 方法

publicvoidacquire()throwsInterruptedException
  • 作用:尝试获取一个许可。如果没有可用的许可,线程会被阻塞,直到有其他线程释放许可。
  • 异常:如果当前线程被中断,则会抛出InterruptedException。

2.2 release() 方法

publicvoidrelease()
  • 作用:释放一个许可,使得其他等待的线程可以继续执行。

2.3 getQueueLength() 方法

publicintgetQueueLength()
  • 作用:返回正在等待获取许可的线程数量。

2.4 availablePermits() 方法

publicintavailablePermits()
  • 作用:返回当前可用的许可数量。

三、Semaphore的应用场景

Semaphore在实际开发中有着广泛的应用,以下是几个常见的使用场景:

3.1 控制并发数

最常见的应用场景就是控制系统的并发线程数。例如,在数据库连接池中,我们通常会限制同时访问数据库的线程数量,以避免服务器过载。

示例代码:

importjava.util.concurrent.Semaphore;publicclassDatabaseConnection{privatestaticfinalintMAX_CONNECTIONS=5;privatestaticSemaphoresemaphore=newSemaphore(MAX_CONNECTIONS);publicvoidgetConnection(){try{// 尝试获取一个许可,最多等待10秒if(semaphore.tryAcquire(10,TimeUnit.SECONDS)){System.out.println(Thread.currentThread().getName()+" 获取到数据库连接");// 模拟数据库操作Thread.sleep(2000);semaphore.release();// 释放许可}else{System.out.println(Thread.currentThread().getName()+" 获取数据库连接超时,放弃请求");}}catch(InterruptedExceptione){Thread.currentThread().interrupt();System.out.println(Thread.currentThread().getName()+" 被中断,退出获取连接操作");}}publicstaticvoidmain(String[]args){DatabaseConnectiondb=newDatabaseConnection();for(inti=0;i<10;i++){Threadthread=newThread(db::getConnection,"Thread-"+i);thread.start();}}}

解释:

  • 我们创建了一个Semaphore对象,初始化时设置为5个许可。
  • 每个线程调用getConnection()方法尝试获取一个许可。最多只能有5个线程同时访问数据库。
  • 如果某个线程在10秒内没有获得许可,则会放弃请求。

3.2 替代ReentrantLock

Semaphore还可以用来替代ReentrantLock,实现更灵活的锁机制。

示例代码:

importjava.util.concurrent.Semaphore;publicclassCounter{privateintcount=0;privateSemaphoresemaphore=newSemaphore(1);// 初始化为1个许可publicvoidincrement(){try{semaphore.acquire();// 获取锁count++;System.out.println(Thread.currentThread().getName()+" 增加到:"+count);Thread.sleep(1000);// 模拟操作时间semaphore.release();// 释放锁}catch(InterruptedExceptione){Thread.currentThread().interrupt();System.out.println(Thread.currentThread().getName()+" 被中断,退出");}}publicstaticvoidmain(String[]args){Countercounter=newCounter();for(inti=0;i<5;i++){Threadthread=newThread(counter::increment,"Thread-"+i);thread.start();}}}

解释:

  • 我们使用Semaphore来实现互斥锁,确保只有一个线程可以执行increment()方法。
  • 这个示例展示了如何将Semaphore作为互斥锁的替代品。

3.3 实现信号量机制

Semaphore最经典的用途就是实现信号量机制。例如,在操作系统中,多个进程需要共享某个资源时,可以通过信号量来协调它们的行为。

示例代码:

importjava.util.concurrent.Semaphore;publicclassSignalExample{privatestaticfinalSemaphoreavailableSem=newSemaphore(0);// 初始没有可用的许可privatestaticfinalSemaphorebusySem=newSemaphore(1);// 初始有一个许可publicstaticvoidmain(String[]args){// 创建生产者线程ThreadproducerThread=newThread(()->{for(inti=0;i<5;i++){try{System.out.println("生产者正在生产...");busySem.acquire();// 等待消费者释放许可availableSem.release();// 通知消费者可以消费了Thread.sleep(100);// 模拟生产时间}catch(InterruptedExceptione){Thread.currentThread().interrupt();System.out.println("生产者被中断,退出");}}},"Producer");// 创建消费者线程ThreadconsumerThread=newThread(()->{for(inti=0;i<5;i++){try{availableSem.acquire();// 等待生产者的通知System.out.println("消费者正在消费...");busySem.release();// 通知生产者可以继续生产了Thread.sleep(100);// 模拟消费时间}catch(InterruptedExceptione){Thread.currentThread().interrupt();System.out.println("消费者被中断,退出");}}},"Consumer");producerThread.start();consumerThread.start();}}

解释:

  • availableSem表示生产者已经生产了商品。
  • busySem表示消费者正在消费商品。
  • 生产者线程在每次生产后都会释放一个availableSem的许可,通知消费者可以开始消费。
  • 消费者线程在每次消费后都会释放一个busySem的许可,通知生产者可以继续生产。

四、总结

通过以上示例可以看出,Semaphore是一个非常强大的工具,它可以用来控制并发数、实现互斥锁以及协调多个线程之间的行为。但在实际使用中,需要注意以下几点:

  1. 线程安全:在多线程环境下,一定要确保Semaphore的操作是原子性的。
  2. 异常处理:当使用acquire()方法时,如果被中断,应该及时释放资源,并进行相应的处理。
  3. 性能问题:虽然Semaphore提供了灵活性,但在某些情况下,可能会引入额外的性能开销。因此,在设计系统时需要权衡利弊。

希望本文能够帮助大家更好地理解和使用Java中的Semaphore

📚 领取 | 1000+ 套高质量面试题大合集(无套路,闫工带你飞一把)!

成体系的面试题,无论你是大佬还是小白,都需要一套JAVA体系的面试题,我已经上岸了!你也想上岸吗?

闫工精心准备了程序准备面试?想系统提升技术实力?闫工精心整理了1000+ 套涵盖前端、后端、算法、数据库、操作系统、网络、设计模式等方向的面试真题 + 详细解析,并附赠高频考点总结、简历模板、面经合集等实用资料!

✅ 覆盖大厂高频题型
✅ 按知识点分类,查漏补缺超方便
✅ 持续更新,助你拿下心仪 Offer!

📥免费领取👉 点击这里获取资料

已帮助数千位开发者成功上岸,下一个就是你!✨

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/18 5:13:56

Gemini 3 Deep Think:企业级部署的性能与成本天平上的舞者

引言 在当今数字化转型的浪潮中,企业对于人工智能技术的应用需求日益增长,Gemini 3 Deep Think 作为谷歌推出的新一代人工智能模型,以其卓越的性能和创新的架构,吸引了众多企业的目光。对于企业而言,在进行技术选型和部署时,成本与性能的平衡是至关重要的考量因素。Gemin…

作者头像 李华
网站建设 2026/3/31 19:01:51

亲测好用9个AI论文工具,本科生轻松搞定毕业论文!

亲测好用9个AI论文工具&#xff0c;本科生轻松搞定毕业论文&#xff01; AI 工具如何助力论文写作&#xff1f; 在如今的学术环境中&#xff0c;越来越多的学生开始借助 AI 工具来提升论文写作效率。对于本科生来说&#xff0c;撰写一篇高质量的毕业论文不仅需要扎实的专业知识…

作者头像 李华
网站建设 2026/3/27 22:22:45

一文说清ST7789的显存组织与像素映射机制

深入ST7789显存与像素映射&#xff1a;从寄存器到屏幕的每一帧如何精准呈现你有没有遇到过这种情况&#xff1f;明明代码里画的是一个方块&#xff0c;结果屏幕上却出来一段斜线&#xff1b;或者UI界面一旋转&#xff0c;文字就倒着显示、颜色发紫……这些问题&#xff0c;往往…

作者头像 李华
网站建设 2026/3/26 13:36:48

谁才是2026年远程控制领域的天花板?9大主流远程控制软件深度横评

在混合办公、跨地域协作、远程创作与云游戏全面普及的2026年&#xff0c;远程控制软件早已不再是IT运维的专属工具&#xff0c;而是成为数字生活中的“水电煤”——不可或缺、高频使用。 面对市场上琳琅满目的选择&#xff0c;用户最关心的问题只有一个&#xff1a;**谁才是真正…

作者头像 李华
网站建设 2026/3/25 13:09:00

【OTA专题】15 实现App后台无感下载固件

目录 软件架构 线程分配&#xff1a; OTA升级协议定义&#xff1a;​编辑 OTA升级流程图&#xff1a; 代码编写&#xff1a; OTA状态机搭建&#xff1a; OTA状态机&#xff1a; SWC_OTA.h文件定义枚举 宏与变量 搭建ota状态机线程 按键扫描函数 软复位函数 W25Q64&…

作者头像 李华