深入AbstractQueuedSynchronized(AQS)源码

AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch等等

源码

盗用一张图,来源http://www.cnblogs.com/waterystone/p/4920797.html
image

AQS通过维护一个private volatile int state,并提供getState(),setState(),compareAndSetState()等方法,让子类对共享变量state进行读写,从而实现以下方法:
1. tryAcquire:获取排它锁。
2. tryRelease: 释放排它锁。
3. tryAcquireShared:获取共享锁。
4. tryReleaseShared:释放共享锁。
5. isHeldExclusively:判断是否为排它策略。

以上5个方法在ReenterLock、ReadWriteLock、CountDownLatch等类中都有实现,到时候再具体分析。
首先来看下AQS中的一个重要数据结构,Node

    static final class Node {
        // 共享锁节点
        static final Node SHARED = new Node();

        // 排它锁节点
        static final Node EXCLUSIVE = null;

        //---------------下面很关键-----------

        // CANCELLED表示该线程不参与竞争了,只有CANCELLED>0,也只有这个状态是表示没用的node
        static final int CANCELLED =  1;

        // 表示该节点的下一个节点需要被唤醒
        static final int SIGNAL    = -1;

        // 表示该节点wait condition
        static final int CONDITION = -2;

        // 这个状态只有共享锁有,表示共享锁需要传播
        static final int PROPAGATE = -3;

        // 取值为CANCELLED、SIGNAL、CONDITION、PROPAGATE、0
        // 0表示啥也不是,用于初始化
        volatile int waitStatus;

        /**
        * 前驱指针,很有用,能够将状态为CANCELLED的节点跳过,直接挂到最近的SIGNAL节点后面
        */
        volatile Node prev;

        /**
        * 用于唤醒后继节点
        */
        volatile Node next;

        // 记录该节点对于的线程
        volatile Thread thread;

        /**
         * 下一个等待condition的节点
         */
        Node nextWaiter;

        // 省略一下方法
    }

下来看AQS中的一下几个重要方法:

  1. acquire
    /**
     * 获取排它锁,忽略中断。方法会调用tryAcquire来获取锁,如果没有获取,则会将当前线程
     * 添加到阻塞队列中,期间可能会被不断阻塞,唤醒并调用tryAcquire,直到tryAcquire获取到锁
     */
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值