,它就是我们之前在讲源码的时候提到的信号量,下面看下它的构造函数。,从构造函数可以看出,它可以传入指定数量的资源和指定公平和非公平锁,公平和非公平就不多阐述了。,我们重点关注的是acquire()和release(), 这两个方法字面意思很好理解, Semaphore往往用于资源有限的场景,比如我们需要限制某个操作的线程数量。下面通过例子感受一下。,实际输出:,我们重点看下acquire()源码实现。,从这个信号量获取一个许可,阻塞直到有一个可用,或者线程被中断。获得一个许可,如果一个可用并立即返回,将可用许可的数量减少一个。,重点是这个sync。,在构造函数中FairSync和NonfairSync他们都继承Sync。,默认情况下非公平的Semaphore会去调用Sync的nonfairTryAcquireShared。,公平的Semaphore内部实现了tryAcquireShared()。,下面我们再回过头看下acquire(), 内部方法acquireSharedInterruptibly是AQS的内部方法。,如果线程中断,直接抛异常, 如果没拿到资源就进入排队机制。,重点看下这个doAcquireSharedInterruptibly()。,shouldParkAfterFailedAcquire()的细节我们也来看下,可能有的同学不大清楚。,这里的SIGNAL一类的常量,大家可以自行到源码查看,这也是细节地方。发现这段代码主要的作用就是检查节点状态,对后续节点做一些操作,这里并没有阻塞操作,下面我们看下parkAndCheckInterrupt()。,这里我们可以看到加了锁,所以阻塞发生在这。那么释放锁在哪呢?其实在release阶段。,可以看到在unparkSuccessor中进行了锁的释放,这个过程发生在释放阶段。,release()相对简单一些,大家可以自己对着源码看下,实现有些类似。,其实本节带大家看源码,主要是想给大家讲下共享锁的知识,Semaphore其实就是使用了共享锁。另外AQS这个类很值得大家好好研究一下,你会发现很多的好用的类都是基于它实现。
© 版权声明
文章版权归作者所有,未经允许请勿转载。