已经习惯了阿里面试官的冷笑:用过Semaphore吧,不妨说说?

本质就是 信号量模型,模型图如下:

其中的 计数器 和 等待队列 对外部是透明的,仅能通过提供的三大方法访问它们。

详细说说哪三大方法?

  • init()

    用于设置计数器的初始值。

  • down()

    计数器-1。若此时计数器<0,则当前线程被 阻塞

  • up()

    计数器+1。若此时计数器≤0,则唤醒 等待队列 中的一个线程,并将其从【等待队列】移除。有同学可能会认为这里的判断条件应该≥0,估计你是理解成生产者-消费者模式中的生产者了。可以反过来想,>0 意味着没有阻塞的线程,所以只有 ≤0 时才需要唤醒一个等待的线程。

down()、up()应配对使用,并按序使用:

  1. 先调用down(),获取锁

  2. 执行处理完后,调用up(),释放锁

若信号量init值为1,并发场景下应该不会出现>0情况,除非故意调先用up(),但这也失去了信号量的意义。

注意,这些方法都是原子性的,由信号量模型的实现方保证。JDK里的信号量模型就是由Semaphore实现,Semaphore保证了这三个方法都是原子操作。

talk is cheap,show me code?

信号量模型中的down()、up()最早被称为P操作和V操作,信号量模型也称PV原语。还有的人会用semWait()和semSignal()表达它们,叫法不同,语义都相同。JUC的acquire()、release()分别对应down()和up()。

如何使用信号量?

就像信号灯,必须先检查是否为绿灯才能通过。比如累加器,count+=1操作是个临界区,只允许一个线程执行,也就是说要保证互斥。 

假设线程t1、t2同时访问add(),当同时调用acquire时,由于acquire是个原子操作,仅会有一个线程(假设t1)把信号量里的计数器减为0,t2则是将计数器减为-1:

  • 对t1,信号量里面的计数器的值是0,≥0,所以t1不会被阻塞,而是继续执行

  • 对t2,信号量里面的计数器的值是-1,<0,所以t2被阻塞

所以此时只有t1会进入临界区执行count+=1。

当t1执行release(),信号量里计数器的值是-1,加1之后的值是0,≤0,根据up(),此时等待队列中的t2会被唤醒。于是t2在t1执行完临界区代码后,才获得进入临界区执行的机会,这就保证了互斥。

既然有JDK提供了Lock,为啥还要提供一个Semaphore ?

实现互斥锁,仅是 Semaphore的部分功能,Semaphore还可以允许多个线程访问一个临界区。

最常见的就是各种池化资源,比如数据库连接池,同一时刻,允许多个线程同时使用连接池。每个连接在被释放前,不允许其他线程使用。

对象池要求一次性创建出N个对象,之后所有的线程重复利用这N个对象,当然对象在被释放前,也是不允许其他线程使用的。所以核心就是限流器,这里的限流指不允许多于N个线程同时进入临界区。

如何快速实现一个这样的限流器呢?

那就是信号量。把计数器的值设置成对象池里对象的个数N即可: 注意这里使用的是 Vector,进入临界区的N个线程不安全。add/remove都是不安全的。比如 ArrayList remove() :

好的,请回家等通知吧!

别再和面试官说不懂信号量Semaphore了!相关推荐

  1. 怎么成为一个优秀的面试官

    转载陈皓--再谈"我是怎么招聘程序员的" 文章目录 转载陈皓--再谈"我是怎么招聘程序员的" 几个重要观点 不要肤浅地认识算法题和智力题 模拟实际中的挑战和能力 ...

  2. 清华毕业生拒绝开摄像头,全程怼面试官

    本文转载自GitHub技术社区 最近,互联网圈子里又现奇葩面试故事,这次是面试官吐槽候选人,先来看看面试官怎么说: 来CDG后第一次面试候选人,候选人是某宇宙厂的战投,清华本科,四年工作经验. 为了尊 ...

  3. 面试官:说说Java中的信号量?Semaphore

    Semaphore (信号量)是由计算机科学家Dijkstra在1965年提出的,广泛应用不同的操作系统,在管程提出之前信号量就是并发编程领域的霸主!几乎所有并发的语言都支持信号量机制. Semaph ...

  4. java semaphore(0)_面试官:说说Java中的信号量?Semaphore

    Semaphore (信号量)是由计算机科学家Dijkstra在1965年提出的,广泛应用不同的操作系统,在管程提出之前信号量就是并发编程领域的霸主!几乎所有并发的语言都支持信号量机制. Semaph ...

  5. 原创 | 我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration

    这是Hollis的第 216 篇原创分享 作者 l cxuan 来源 l Hollis(ID:hollischuang) 现在大部分的Spring项目都采用了基于注解的配置,采用了@Configura ...

  6. 我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration

    作者 l cxuan 来源 l Hollis(ID:hollischuang) 现在大部分的Spring项目都采用了基于注解的配置,采用了@Configuration 替换标签的做法.一行简单的注解就 ...

  7. 不懂性能测试,被面试官挂了...

    性能测试旨在检查应用程序或软件在特定负载下工作时的响应性和稳定性,从而检测应用程序/软件在响应速度.可扩展性和稳定性方面是否达到预期的要求. 简而言之,性能测试目标就是为了识别并消除应用程序中的性能瓶 ...

  8. 软件测试简历?面试题?企业面试官想要什么?我不再和offer失之交臂...

    目录:导读 前言 一.Python编程入门到精通 二.接口自动化项目实战 三.Web自动化项目实战 四.App自动化项目实战 五.一线大厂简历 六.测试开发DevOps体系 七.常用自动化测试工具 八 ...

  9. 阿里面试官:Redis分片集群都不懂?还来面试?

    面试官:聊下Redis的分片集群,先聊 Redis Cluster好咯? 面试官:Redis Cluser是Redis 3.x才有的官方集群方案,这块你了解多少? 候选者:嗯,要不还是从基础讲起呗? ...

最新文章

  1. 深入理解Spring系列之六:bean初始化
  2. 03-2 BGP专有命令--BGP命令与配置手册
  3. VMware虚拟机提示在该系统上全局禁用了虚拟机打印功能
  4. 如何用MathType插入公式编号
  5. 微型计算机芯片总称,《计算机应用基础》2(G)在线作业答案
  6. bzoj1084: [SCOI2005]最大子矩阵
  7. 数据科学中的数据可视化
  8. java三目运算_Java中的三目运算符 详解
  9. PRISM ‘VS100COMNTOOLS’ not set. Cannot set the build environment
  10. eclipsenbsp;mavennbsp;pluginamp;n…
  11. SAP开源Java SCA工具,提供静态代码安全性测试功能
  12. 实战weblogic集群之创建节点和集群
  13. flink EventTime与Window
  14. oci8 php,PHP_试用php中oci8扩展,给大家分享个php操作Oracle的操 - phpStudy
  15. Java工程师两周面试突击-中华石杉-Java面试
  16. java实现短信通知、验证码
  17. 4.证券投资基金的监管
  18. 微信支付之App支付
  19. 小程序利用background-image设置背景
  20. 【Mysql面试宝典】快速搞定Mysql表操作

热门文章

  1. oracle备份保留3天,【错误更正】oracle 备份: 每天备份,全备份,保留七天。...
  2. Java非阻塞I/O模型之NIO说明
  3. poj1419(最大独立集)
  4. 2021牛客暑期多校训练营3 I-Kuriyama Mirai and Exclusive Or (差分+位运算)
  5. Codeforces Global Round 9 A-D题解
  6. python生成word目录_Word&Python-创建目录
  7. html 视频兼容苹果,video苹果兼容flash播放
  8. 《挑战程序设计竞赛(第2版)》习题册攻略
  9. poj3484详解(二分)
  10. sql定位过程报错_如何得到plsql中执行时报错的SQL的位置行号