很多人都听说过Java里有个叫AQS的东西,其实AQS只是Java里的一个类 AbstractQueuedSynchronizer
的缩写,当我们谈论AQS时,更多的是指那些利用AQS实现的同步工具类,比如 Semaphore
、 CountDownLatch
、 ReentrantLock
等。
那么什么是同步工具类呢?
打个比方,你开了一家饭馆,可以容纳10桌客人同时吃饭。来客人了,如果里头吃饭的不到10桌,那么请进,如果已经有10桌在吃了,那不好意思,请排队。
同样是排队,这一次,你不开饭馆了,你组织了一个饭局,邀请了10个人过来,人齐了才能开吃,这下排队的规则就变了,客人来了,看看到场的人到没到10个,到了,好,开吃,没到,不好意思,咱们继续聊聊天,玩玩手机,等那个该死的迟到的家伙。
排队的规则不尽相同,但也有相同的地方,那就是你总要安顿好排队的客人吧?当可以进来吃饭的时候,你需要取通知客人吧?
这些各种排队系统都需要的东西,比如安顿客人、通知客人用餐,就是AQS干的活,至于具体的排队规则,则是交给具体的同步工具类去制定。
你要安顿的不是客人,而是线程,你要把等待的线程,放到一个队列中去,然后把它们挂起,不让它们乱动,浪费CPU;然后,在合适的时候,唤醒这些线程。
二进制世界里, Semaphore
就是上面说的饭馆,专业点的翻译,叫 信号量
,总共10个permits,进来一个线程,就拿走一个,拿完了,其他线程就不能进来,只能等待拿到permit的线程,释放permit,这时候其他线程才有机会进去。
而 CountDownLatch
,没错,就是饭局,你设置了一个减数器,初始值为10,每来一个线程,减掉一个,减完还不等于0,那么线程等待,减到0时,ok,全部唤醒,放行。
Semaphore
、 CountDownLatch
、 ReentrantLock
这些同步工具类,要做的,就只是写下自己的排队规则,所以看源码,你会发现这些类,注释比代码还多。
Talk is cheap. Show me the code?
Sorry, 这是一篇无码的文章。
了解AQS的原理,主要是为了更好的弄懂我们经常使用的这些同步工具类的运行机制,出了问题,好知道原因。
这里稍微分享下AQS源码里的几个关键词吧:
CountDownLatch
即可 AbstractQueuedSynchronizer
里一个万能的属性,具体是什么含义,全看你的使用方式,比如在 CountDownLatch
里,它代表了当前到达后正在等待的线程数,在 Semaphore
里,它则表示当前进去后正在运行的线程数 这篇文章只是一个引子,如果你想深入学习AQS,可以自己写几个demo,然后调试看看,也可以看看我们组一位大佬写的文章: 天外流星for
以上。
Previous
哈姆雷特,活着,寂寞的游戏