




NO.1
懵逼树上懵逼果,懵逼树下你和我。懵逼树下排排坐,一人一个懵逼果。

NO.2
说起AQS就是一脸懵逼,到底什么是AQS?

NO.3
说AQS之前咱们来讨论一下锁的本质(一分钟看透事物本质与一年看透事物本质的人必然是不同的人生)。
JAVA中锁的设计初衷是处理并发问题,作为多线程共享的资源,当出现并发访问的时候,我们需要合理的控制资源的访问规则,而锁就是用来实现这些访问规则的重要数据结构。

NO.4
很多人都听说过Java里有个叫AQS的东西,其实AQS只是Java里的一个类AbstractQueuedSynchronizer的缩写,当我们谈论AQS时,更多的是指那些利用AQS实现的同步工具类,比如Semaphore、CountDownLatch、ReentrantLock等。
举个栗子:你开了一个加油站,有6个加油枪。有司机来加油了,如果加油站里加油的不到6个,那么司机可以进来加油。如果已经有6个司机在加油了,那不好意思,请排队。
同样是排队,这一次你不搞加油站了,你搞了一个游乐园,有一个大摆锤的项目。每次可以做6个人,人齐了才能开动。这下排队的规则就变了,游客来了,看看到场的人有木有6个,齐了,好,开动。不齐,不好意思,游客继续聊聊天天,玩玩手机,等喜欢刺激的人到来。

NO.5
排队的规则不同,但也有相同的地方,那就是你总要安排好司机,游客吧?当可以进来加油的时候,你需要开加油枪吧?
这些各种排队系统都需要的东西,比如开加油枪,打开大摆锤开关,就是AQS干的活,至于具体的排队规则,则是交给具体的同步工具类去指定。

NO.6
现在让我们穿越到二进制的世界中,现在,你要同步的,不再是人,而是线程。
你要安顿的不是人,而是线程,你要把等待的线程,放到一个队列中去,然后把它们挂起,不让它们乱动,浪费CPU;然后在合适的时候,唤醒这些线程。
二进制世界里,Semaphore就是上面说的加油站,专业点的翻译,叫信号量,总共6个permits,进来一个线程,就拿走一个,拿完了,其他线程就不能进来,只能等待拿到permit的线程,释放permit,这时候其他线程才有机会进去。
而CountDownLatch,没错,就是大摆锤,你设置了一个减数器,初始值为6,每来一个线程,减掉一个,减完还不等于0,那么线程等待,减到0时,ok,全部唤醒,放行。
Semaphore、CountDownLatch、ReentrantLock这些同步工具类,要做的,就只是写下自己的排队规则,所以看源码,你会发现这些类,注释比代码还多。

NO.7
前面介绍了一下AQS与锁,那AQS与锁又有什么关系呢?相信聪明的你,已经心里有所感悟了,AQS就是控制排队规则,锁是控制资源的访问规则。不多不少,刚刚好,我们可以用AQS实现“锁”机制,所以我们会发现基于AQS实现的多钟锁的工具类,自旋锁、互斥锁、读锁写锁、条件产量、信号量、栅栏都是AQS的衍生物。这些类内部持有一个AbstractQuenedSynchronizer的实例,通过该实例,实现共享、独占等特性。

分享给你第一个想到的人




