Description
如上图:
关于文章中的:
“ Semaphore(信号量)可以指定多个线程同时访问某个资源。”
这句话在我阅读源码后发现,Semaphore 可以指定一次性可以指定最多 permits个线程执行任务,而不是 : "同时",因为Semaphore它的实现是只要AQS的state>0 == true,那么线程通过不断自旋CAS,就有机会获得执行任务的机会,所以只要在线程自旋期间,state是大于0的,那么任何一个线程都有可能判断成功,而不是多个线程同时成功。。
然后关于这部分AQS组件的描述个人认为有点模糊不清,所以我在整理后重新组织了下语言:
CountDownLatch
CountDownLatch允许count个线程阻塞在一个地方,直至所有线程的任务都执行完毕。
CountDownLatch是共享锁的一种实现,它默认构造AQS的state为count。
当线程使用countDown方法时,其实使用了tryReleaseShared方法以CAS的操作来减少state,
直至state为0就代表所有的线程都调用了countDown方法。当调用await方法的时候,如果state不为0,就代表仍然有线程没有调用countDown方法,那么就把已经调用过countDown的线程都放入阻塞队列Park,并自旋CAS判断state == 0,直至最后一个线程调用了countDown,使得state == 0,
于是阻塞的线程便判断成功,全部往下执行。
Semaphore
Semaphore允许一次性最多(不是同时)permits个线程执行任务。
Semaphore与CountDownLatch一样,也是共享锁的一种实现。
它默认构造AQS的state为permits。当执行任务的线程数量超出permits,那么多余的线程将会被放入阻塞队列Park,并自旋判断state是否大于0。
只有当state大于0的时候,阻塞的线程才能继续执行,此时先前执行任务的线程继续执行release方法,
release方法使得state的变量会加1,那么自旋的线程便会判断成功。
如此,每次只有最多不超过permits数量的线程能自旋成功,便限制了执行任务线程的数量。所以这也是我为什么说它可能不是permits个线程同时执行,
因为只要state>0,线程就有机会执行.
CycliBarrier
CycliBarrier的功能与CountDownLatch相似,但是CountDownLatch的实现是基于AQS的,
而CycliBarrier是基于ReentrantLock(ReentrantLock也属于AQS同步器)和Condition的.
CountDownLatch虽然可以令线程阻塞,但是CountDownLatch只能await一次就不能使用了,
而CycliBarrier有Generation代的概念,一个代,就代表CycliBarrier的一个循环,
这也是CycliBarrier支持重复await的原因。
老哥可以选择性的更改下错误的部分。。。