已经习惯了阿里面试官的冷笑:用过Semaphore吧,不妨说说?
本质就是 信号量模型,模型图如下:
其中的 计数器 和 等待队列 对外部是透明的,仅能通过提供的三大方法访问它们。 详细说说哪三大方法?
init()
用于设置计数器的初始值。
down()
计数器-1。若此时计数器0 意味着没有阻塞的线程,所以只有 ≤0 时才需要唤醒一个等待的线程。
down()、up()应配对使用,并按序使用:
先调用down(),获取锁 执行处理完后,调用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,
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?