• 末日,成欢
    2022-07-23 来自上海
    对于AQS框架的理解, 我的感觉它更像是synchronized的JAVA实现。 在进入synchronized代码内部的时候, 是通过monitorenter指令, 修改了对象头的Markword. AQS在进入的时候, 通过CAS修改了state变量。 释放的时候同理。 当多个线程阻塞排队的时候, synchonized同样存在入口的等待队列EntryList,和AQS类似。 当使用wait/notifyAll的时候, synchronized同样存在条件队列waiSet, 也和AQS的条件队列类似。 持有线程ownerThread,也是类似的。 AQS又是对synchronized的功能的增强。 比如增加了非阻塞式锁,支持打断式获取锁、支持超时式获取锁。 并且大师们更对AQS实现了公平锁、非公平锁,还有一些更好用的工具类。 ReentrantReadWriteLock也是使用AQS实现的。 它对state的高低16位有更多的功能。 读用的是高16位,写用的是低16位 并且读锁使用的是共享模式, 也就是当写锁释放时, 会将读线程一个一个唤醒。

    作者回复: 嗯,对的,非常不错,我当时就认真看了大师写的AQS,才真正对锁有了正确的认知,正确认知锁后,对多线程并发编程就能得心应手。

    
    7
  • 码小呆
    2022-06-26
    感觉一遍还不够我大脑理解,需要多看看!

    作者回复: 你好,在看的过程中,如果有什么疑问,可以找我细聊

    
    1
  • :)
    2022-06-25 来自上海
    老师,你好, 看了下源码ReentrantLock 是 implements Lock 而不是 extends ,为什么还用内部类Sync,而不是直接extends AbstractQueuedSynchronizer?

    作者回复: 你好,你这个问题问的非常好。我发表一下我的一些看法,欢迎探讨执教。 这里其实涉及到设计模式的一些实践。 AbstractQueuedSynchronizer 这个类,主要用来定义一些锁的共同方法,锁的一些模版方法,但锁的类型有读写锁、公平锁,公平锁、信号量、CountDownlatch,这些都有一些共性方法,但他们之间又很多差异,如果继承一个基类,由于存在较大差异,代码会很乱,并且受限于java单继承机制,所以就采用来内部类,来解决多重继承,并且引入两个维度。

    共 2 条评论
    1
  • 小豹哥
    2022-06-24 来自上海
    这也太仔细认真了吧,这细节抠的! 给老师点个大大的赞

    作者回复: 谢谢认可,之所以我在这花这么大的篇幅在介绍juc中锁的实现,是因为我从一个毫无高并发编程经验的菜鸟,慢慢通过研读juc这块的代码,从而对多线程编程有了实打实的在原理层面的开窍,就是有那种悟道、豁然开朗的感觉。

    
    1
  • TableBear
    2022-07-06
    老师,请问你的源码是JDK什么版本的?

    作者回复: 你好,使用的版本是jdk1.8的

    共 2 条评论
    
  • 雨落~紫竹
    2022-07-02
    我又来了

    作者回复: 谢谢你的互动,期待我们更多的技术碰撞,一起进步。

    
    
  • smilekaka
    2023-07-26 来自江苏
    太干了,有点噎住....
    
    
  • 小麦
    2022-08-04 来自广东
    “如果节点的状态为 Node.CONDITION,或者 node.prev 为空,表示线程在等待条件被触发。为什么节点的前驱节点不为空就可以认为线程在同步阻塞队列中呢?这是因为进入同步队列时是用 CAS 机制来更新前驱节点的。” AQS 貌似没有通过 CAS 更新前驱节点的操作。 private static final long stateOffset; private static final long headOffset; private static final long tailOffset; private static final long waitStatusOffset; private static final long nextOffset; 没看到有前驱节点的偏移量。
    
    
  • Zx
    2022-06-27
    有一个小问题请教老师,为什么唤醒节点要从队尾开始找最靠前的非取消节点,而不是从队头开始找呢
    共 1 条评论
    