Java AQS无码讲解

作者 : 开心源码 本文共1514个字,预计阅读时间需要4分钟 发布时间: 2022-05-12 共51人阅读

很多人都听说过Java里有个叫AQS的东西,其实AQS只是Java里的一个类AbstractQueuedSynchronizer的缩写,当我们谈论AQS时,更多的是指那些利用AQS实现的同步工具类,比方SemaphoreCountDownLatchReentrantLock等。

那么什么是同步工具类呢?

打个比如,你开了一家饭馆,可以容纳10桌客人同时吃饭。来客人了,假如里头吃饭的不到10桌,那么请进,假如已经有10桌在吃了,那不好心思,请排队。

同样是排队,这一次,你不开饭馆了,你组织了一个饭局,邀请了10个人过来,人齐了才能开吃,这下排队的规则就变了,客人来了,看看到场的人到没到10个,到了,好,开吃,没到,不好心思,咱们继续聊聊天,玩玩手机,等那个该死的迟到的家伙。

排队的规则不尽相同,但也有相同的地方,那就是你总要安顿好排队的客人吧?当可以进来吃饭的时候,你需要取通知客人吧?

这些各种排队系统都需要的东西,比方安顿客人、通知客人用餐,就是AQS干的活,至于具体的排队规则,则是交给具体的同步工具类去制定。

现在让我们回到二进制世界中,现在,你要同步的,不再是人,而是线程。

你要安顿的不是客人,而是线程,你要把等待的线程,放到一个队列中去,而后把它们挂起,不让它们乱动,白费CPU;而后,在合适的时候,唤醒这些线程。

二进制世界里,Semaphore就是上面说的饭馆,专业点的翻译,叫信号量,总共10个permits,进来一个线程,就拿走一个,拿完了,其余线程就不能进来,只能等待拿到permit的线程,释放permit,这时候其余线程才有机会进去。

CountDownLatch,没错,就是饭局,你设置了一个减数器,初始值为10,每来一个线程,减掉一个,减完还不等于0,那么线程等待,减到0时,ok,一律唤醒,放行。

SemaphoreCountDownLatchReentrantLock这些同步工具类,要做的,就只是写下自己的排队规则,所以看源码,你会发现这些类,注释比代码还多。

Talk is cheap. Show me the code?

Sorry, 这是一篇无码的文章。

理解AQS的原理,主要是为了更好的弄懂我们经常使用的这些同步工具类的运行机制,出了问题,好知道起因。

这里略微分享下AQS源码里的几个关键词吧:

  • 组合:Effective Java里提到,组合是比继承更好的复用代码的方式,Java源码里通过组合的方式来复用AQS的,具体如何组合,看看CountDownLatch就可
  • state状态:这是AbstractQueuedSynchronizer里一个万能的属性,具体是什么含义,全看你的使用方式,比方在CountDownLatch里,它代表了当前到达后正在等待的线程数,在Semaphore里,它则表示当前进去后正在运行的线程数
  • CAS: AQS里大量用了CAS操作来修改state的值
  • LockSupport: AQS里用了大量的LockSupport的park()和unpark()方法,来挂起和唤醒线程
  • 同步队列和条件队列:sync queue and condition queue,弄清楚这两个队列的关系,AQS也就弄懂大半
  • 公平和非公平:有线程竞争,就有公平和非公平的问题。锁释放的时候,恰好有个线程过来获取锁,但这时候线程等待队列里也有线程在等待,究竟是给排队时间最久的线程呢(公平),还是允许新来的线程参加竞争(不公平)?

这篇文章只是一个引子,假如你想深入学习AQS,可以自己写几个demo,而后调试看看,也可以看看我们组一位大佬写的文章:天外流星for

以上。

参考

  • Java Concurrency in Practice

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Java AQS无码讲解

发表回复