上一期介绍了CyclicBarrier的源码解析,今天来聊一聊最后一个工具:信号量 Semaphore。Semaphore用来控制同时操作某个资源的操作数量。Semaphore管理着permits,每当一个线程来获取许可时,permits数减1,当permits数小于0时,再来获取许可的资源就需要阻塞。下面来详细看看Semaphore的实现原理。
内部类
Semaphore支持公平和非公平两种实现。
构造方法
permits表示许可的数量,需要在创建Semaphore的时候赋值,Semaphore默认为非公平的。
如果要使用公平的,则需要指定fair参数为true。
方法
acquire
acquire方法调用了Sync的acquireSharedInterruptibly方法
tryAcquireShared方法在Semaphore中分为公平和非公平的两种方式,公平的方式会先去判断前面有没有排队获取许可的线程,如果有说明许可是小于0的,所以直接返回-1。之后公平和非公平的操作是相同的,都是获取state值,减1,通过cas的方式更新state值,返回更新后的值。
tryAcquireShared返回的值如果小于0,说明许可值不够了,需要去排队等待。
release
release方法释放一个许可,把它归还给Semaphore,然后把可用的许可(permits)数目加1。
release额方法调用了AQS的releaseShared方法
tryReleaseShared方法通过cas的方式把当前的state值更新为state+arg。
doReleaseShared的操作在CountDownLatch的countDown方法中也有用到,大家可以去参照countDown方法Java并发工具三剑客之CountDownLatch源码解析
示例
Semaphore的源码中给出了使用的实例,大家可以参考,毕竟官方的肯定是很有指导意义的。