AQS梳理:
以ReentrantLock为例
1、内部抽象类Sync继承了AbstractQueuedSynchronizer(state为volatile修饰),继承AbstractQueuedSynchronizer的类要实现抽象方法tryAcquire(int acquires),tryRelease(int acquires)等等
1、Sync包含方法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的值为1(compareAndSetState(0, 1)),如果成功,则设置当前线程为ExclusiveOwnerThread
b).如果失败,则调用acquire(1)排队获取锁,这个是AbstractQueuedSynchronizer里实现好的方法,调用了tryAcquire尝试加锁和acquireQueued放入对列的操作
acquire(1):
a).tryAcquire(int arg):是暴露给继承AbstractQueuedSynchronizer的类实现的操作(比如NonfairSync和FairSync),让继承者自定义
加锁逻辑
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()