脚本宝典收集整理的这篇文章主要介绍了

读源码笔记 Java AbstractQueuedSynchronizer

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

AQS Condition

最近面试被问到java concurrent包下有哪些熟悉的,用过的工具。因此来回顾一下,这些工具的底层实现,AbstractQueuedSynchronizer。在网上看到了其他人的一些技术博客,我将源码贴出,分享下自己不同的见解。
读源码笔记 Java AbstractQueuedSynchronizer-脚本宝典
clipboard.png

分析源码

对于初看源码的我来说,很奇怪,为什么明明“waitThread1”已经拿到锁的情况下,而“singalThread”还能获取同样的锁而运行呢。这就得看源码才能分析明白。
一开始waitThread拿到了锁,然后调用了condition调用了await方法。
看看await方法:
clipboard.png

  1. 首先方法中会构建一个node用来表示该node现在在Condition的queue中。Condition的queue维护着一连串的node,当前线程被包含在其中。

  2. 接下来fullyRelease方法会将AQS的当前状态即state置为0(这里说的是具体的ReentrantLock的tryRelease实现方式,因为它是独占锁。)fullyRelease其中还会将AQS中维护的queue(其中同样是node,只是Condition中的node记录的是等待condition的node,AQS中的queue是等待锁的node)中的线程释放出来。注意,执行完这一步之后,若另一个线程singalThread由于lock而得不到锁,已经在AQS的queue中,处于wait状态,这时他将被唤醒,然后获取到锁,从AQS的queue中删除。

  3. 当singalThread执行完singal的之中,就会将condition中的node移到AQS的queue上去。
    具体代码在condition中的signal方法中:

clipboard.png

将其node的状态改为SIGNAL,注意这个时候一般node还没有被唤醒。
clipboard.png

通常上面这一句不会为true,除非没有能把目前node的状态改为SIGNAL,或者node state大于0了,这个时候说明任务呗取消了,那么以上两种情况都直接唤醒线程。除了上述两种情况外,由signalthread的unlock操作唤醒在AQS上的线程。

总结

总的来说,操作顺序是:

  1. waitthread lock

  2. Signalthread lock 进入AQS队列wait

  3. waitthread await 唤醒 Signalthread,Signalthread成功获得锁

  4. Signalthread signal 将waitthread 状态变为signal并将其从condition queue转到AQS queue

  5. Signalthread unlock 使waitthread再次获得锁 执行余下代码。
    当然这是理由状态下,为了讨论AQS及condition的原理,实际的操作时序也有可能变化。

总结

以上是脚本宝典为你收集整理的

读源码笔记 Java AbstractQueuedSynchronizer

全部内容,希望文章能够帮你解决

读源码笔记 Java AbstractQueuedSynchronizer

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过