Semaphore源码分析
2019-09-16 本文已影响0人
SnailFast
整体概况
Semaphore是借助AQS实现的的共享锁,通过构造参数可以给状态变量赋值,用来控制对资源访问的并发度。Semaphore代码很简洁,主要方法就两个,一个是获取资源许可方法acquire,一个是释放资源方法release,这两个方法都是利用内部的同步器对状态变量的控制来实现的,整体源码结构如下图所示。

Sync
和ReentrantLock类似,Semaphore内部的AQS同步控制器也分为公平和非公平两种,区别只是在获取资源许可的时候是否会考虑排队队列情况。NonfairSync不会考虑队列情况,当资源数量不为0时,死循环一直抢占,直到抢到资源许可或者资源数量为0为止。而FairSync在获取锁时会考虑现有队列情况,如果队列中有其他线程在排队,则当前线程直接去排队。源代码情况如下图所示。


acquire
Semaphore获取资源许可的方法,实现方式是借助内部的AQS同步控制器将资源数量减1,可以通过Semaphore的构造函数来选择acquire方法的实现是公平的还是非公平的。源代码情况如下图所示。



release
Semaphore释放获取的方法,实现方式是借助内部的AQS同步控制器将资源数量加1,死循环一直调用CAS方法。源代码情况如下图所示。



注意,由于tryReleaseShared方法没有对状态变量的上限做保护,所以一定要在调用acquire方法之后再调用release方法,不然可能会使资源许可的数量超过Semaphore构造函数设置的值,导致过多的线程对资源的并发访问。