AQS原理

作者: couriravant | 来源:发表于2020-01-02 17:36 被阅读0次

    分为独占锁和共享锁:

    获取独占锁:

    image.png
     final void lock() {
                if (compareAndSetState(0, 1))
                    setExclusiveOwnerThread(Thread.currentThread());
                else
                    acquire(1);
            }
    

    CAS设置为1,成功则获取锁,否则调用 acquire获取锁

     public final void acquire(int arg) {
            if (!tryAcquire(arg) &&
                acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
                selfInterrupt();
        }
    

    tryAcquire 作用也是做CAS获取锁,如果已经是同一线程重入,state+1(释放时会减1),如果ryAcquire成功就结束,如果没有成功,则通过addWaiter将当前线程包装成一个Node节点,通过CAS原子操作,加入队列的尾部.
    acquireQueued() 中会判断这个node节点的前一个节点是不是head节点(也就是持有锁的节点),如果是,那就调用tryAcquire再次通过CAS自旋去尝试获取锁,如果获取锁失败后,进入挂起逻辑。

    总结:

    在独占锁模式下,用 state 值表示锁并且 0 表示无锁状态,0 -> 1 表示从无锁到有锁,仅允许一条线程持有锁,其余的线程会被包装成一个 Node 节点放到队列中进行挂起,队列中的头节点表示当前正在执行的线程,当头节点释放后会唤醒后继节点,从而印证了 AQS 的队列是一个 FIFO 同步队列。

    获取共享锁:

    共享功能:只要头节点获取锁成功,就在唤醒自身节点对应的线程的同时,继续唤醒AQS队列中的下一个节点的线程,
    每个节点在唤醒自身的同时还会唤醒下一个节点对应的线程,以实现共享状态的“向后传播”,从而实现共享功能。

    refer:https://www.jianshu.com/p/76949bca657a
    http://objcoding.com/2019/05/05/aqs-exclusive-lock/

    相关文章

      网友评论

          本文标题:AQS原理

          本文链接:https://www.haomeiwen.com/subject/ayjooctx.html