AQS梳理

132 阅读2分钟
AQS梳理:
以ReentrantLock为例
1、内部抽象类Sync继承了AbstractQueuedSynchronizer(state为volatile修饰),继承AbstractQueuedSynchronizer的类要实现抽象方法tryAcquire(int acquires),tryRelease(int acquires)等等
    1Sync包含方法lock()、普通方法nonfairTryAcquire(int acquires)、普通方法tryRelease(int acquires)
        nonfairTryAcquire(int acquires):
            a).获取state,如果state为0,则使用compareAndSetState(CAS)设置state为acquires,并设置当前线程为ExclusiveOwnerThread(拥有锁的线程)
            b).如果state不为0,且当前线程为锁拥有线程,则设置state的值+acquires
            c).不满足上述条件则返回false
        tryRelease(int acquires):
            a).正常情况下,调用tryRelease(int acquires)的线程是持有锁的线程,如果不是,则会抛出IllegalMonitorStateException
            b).设置state的值为state-releases,如果计算为0,则设置锁状态为free=true,并置空ExclusiveOwnerThread
        isHeldExclusively():判断当前线程是否为ExclusiveOwnerThread
        .......
    2、内部类NonfairSync(非公平锁的实现类)继承Sync,实现lock()和tryAcquire(int acquires)
        lock():
            a).默认无锁,直接cas设置state的值为1compareAndSetState(0, 1)),如果成功,则设置当前线程为ExclusiveOwnerThread
            b).如果失败,则调用acquire(1)排队获取锁,这个是AbstractQueuedSynchronizer里实现好的方法,调用了tryAcquire尝试加锁和acquireQueued放入对列的操作
                acquire(1):
                    a).tryAcquire(int arg):是暴露给继承AbstractQueuedSynchronizer的类实现的操作(比如NonfairSyncFairSync),让继承者自定义
                        加锁逻辑
                    b).addWaiter(Node mode),将当前节点加入等待队列尾部,是AbstractQueuedSynchronizer已经实现好的,继承者不用考虑
                        1.使用cas将node添加到后面,如果失败,调用enq(Node mode)来添加,采用死循环cas的自旋方式,确保添加一定成功
                    c).acquireQueued(final Node node, int arg),顺带获取一次锁
        tryAcquire(int acquires):
            a).直接调用Sync中的nonfairTryAcquire(int acquires),ReentrantLock默认的是非公平锁的方式获取锁
    3、内部类FairSync(公平锁实现类)继承Sync,实现lock()和tryAcquire(int acquires)
        lock():
            a).直接调用acquire(1)排队去获取锁
        tryAcquire(int acquires):
            a).获取state,如果state为0,判断等待队列有没有线程,没有,则使用cas设置state的值,并设置当前线程为锁拥有线程
            b).如果state不为0,判断当前线程是否为锁拥有线程,如果是,则设置state的值+acquires
            c).不满足上述条件则返回false

2.tryLock():
    a).直接调用sync.nonfairTryAcquires使用非公平方式获取锁

3.tryLock(long timeout, TimeUnit unit):
    a).调用sync.tryAcquireNanos(1, unit.toNanos(timeout)),sync的具体实现在实例化ReentrantLock的时候实例化,默认NonfairSync
        tryAcquireNanos(1, unit.toNanos(timeout)):
            a).不管三七二十一,先调一次tryAcquire尝试获取下锁,失败了,再调用doAcquireNanos(int arg, long nanosTimeout),转到公平的方式获取锁
            b).将当前线程加入队列末尾addWaiter,自旋传入时间,判断是否轮到他

4.unlock():
    a).sync.release(1):这个是AQS里的方法,这个方法调了tryRelease(1)(这个方法是由继承了AQS的类去实现的)和unparkSuccessor(h),

5.newCondition():
    a).sync.newCondition()