看完这篇,面试官问Semaphore,我能吹半小时

软件求生 2025-04-24 09:46:29



嗨!大家好,我是你们熟悉的 31 岁程序员小米,一个喜欢写代码、讲故事、做饭、撸猫、写公众号的人。

今天这篇文章,咱们继续讲点面试中高频但是常被忽视的 Java 多线程知识点。最近我一个老同事去面试,HR 问了个看似简单但实际很多人讲不清楚的问题:

Semaphore 有什么作用?它和锁有什么区别?能不能举个生活里的例子说明一下?

老同事回来跟我吐槽:“小米啊,我平时用 synchronized、ReentrantLock 用得顺溜,轮到 Semaphore 就懵圈,面试时候只说出是‘限流’用的,面试官明显不满意。”

好家伙,咱这不行啊。

既然如此,今天我就跟大家唠个透彻,顺便给正在准备社招的小伙伴打打鸡血,整理一波知识点!

Semaphore 是个啥玩意?

咱先别忙着看代码,先来点接地气的故事。

故事时间:小米去健身房抢跑步机

我最近开始减肥,报名了个健身房。健身房里有 5 台跑步机,大家都可以去跑,但总不能无限人一起跑对吧,最多只能同时用 5 台。

如果我去的时候,跑步机还有空位,我就可以上去开跑;如果 5 台都被人用了,我只能等着,等有个人跑完下来,释放一台跑步机,我再上去跑。

跑步机 = 资源

排队的人 = 线程

健身房规则 = Semaphore 控制

Semaphore 的作用就像健身房里的“跑步机空位指示灯”:

5 个指示灯亮着,说明还能进 5 个;

灭了,说明得等,有人下来才有空。

总结一句话:Semaphore 是一个计数器,控制同时访问某个特定资源的线程数量。

Semaphore 怎么用?

咱这就来写段 Java 代码,把健身房的场景搬进代码里

核心方法:

Semaphore.acquire():申请一个许可,如果没有就阻塞等待。

Semaphore.release():释放一个许可,让其他线程继续抢。

这样就实现了最多 5 个人同时用跑步机。

和 synchronized、ReentrantLock 有啥区别?

很多朋友一看 Semaphore,心里就犯嘀咕:“我用 synchronized 不也能保证线程安全吗?ReentrantLock 也行啊,干嘛还搞个 Semaphore?”

咱来对比下

也就是说:

synchronized、ReentrantLock 是“互斥锁”,一次只允许一个线程进入。

Semaphore 更灵活,允许多个线程同时访问,但数量有限制。

这也是为什么很多限流场景、连接池、资源池管理里,Semaphore 是首选。

常见使用场景

面试答题最忌空泛,一定得举例子,实打实。

我来整理一下工作中常用的 5 个场景:

1. 限流

比如一个接口最多允许 10 个并发请求,超过的排队。

每个请求到来先 acquire(),走完逻辑 release()。

2. 资源池管理

比如数据库连接池、线程池,最多给定数量的资源,控制并发数量。

3. 多线程限量执行

比如有 50 个线程,但我只希望最多 5 个一起干活,干完一批,再放下一批。

4. 生产者-消费者模型

比 synchronized 更灵活地控制消费者数量。

5. 实现死锁演示

如果 acquire() 顺序写反,就很容易模拟死锁。

延伸知识:Semaphore 怎么实现的?

如果你对底层好奇,咱简单说下。

Semaphore 本质上是基于 AQS(AbstractQueuedSynchronizer) 实现的。

核心变量:

而 Sync 里维护了一个 state 值,表示可用许可证数量。

acquire() 其实是尝试把 state--,如果小于 0 就排队阻塞。

release() 则是 state++,然后唤醒队列里的线程。

是不是感觉和锁有点类似?没错,AQS 就是个超强的同步框架,ReentrantLock、CountDownLatch、Semaphore 都是基于它。

面试答题模板

最后,我来给大家写个标准答题模板,方便社招面试时候用。

题目:Semaphore 有什么作用?和锁有什么区别?举个例子说明。

答:

Semaphore 是一个用于控制同时访问某个特定资源的线程数量的同步工具。它内部维护一个许可证计数器,每个线程在访问资源前需要先获取许可,访问结束后再释放许可。

和锁(synchronized / ReentrantLock)相比,锁是排他锁,一次只允许一个线程访问资源,而 Semaphore 可以同时允许多个线程访问,数量由许可数决定,更适合限流、资源池管理、连接池等场景。

举个例子,比如健身房有 5 台跑步机,最多允许 5 个人同时使用,Semaphore 就相当于跑步机的空位计数器,满了就得等,空了就能上。

写在最后

兄弟姐妹们,看完这篇,是不是觉得 Semaphore 没那么神秘了?

其实很多面试题,关键在于你能不能讲清楚它在实际生活/工作中的作用,而不是光背 API。

我这次用健身房跑步机的例子,希望能帮你把这个概念记牢。如果觉得有用,别忘了点个“在看” 和 “转发”支持一下!

END

你们要是感兴趣,下期我来写:

CountDownLatch 和 CyclicBarrier 的区别

Java 多线程限流实战

手撸线程池

咱们下期见!小米敬上~

0 阅读:0

软件求生

简介:从事软件开发,分享“技术”、“运营”、“产品”等。