AQS理解
(volatile)status 和 监控status的双向链表,每个链表里面有一个节点node,node里面装的是thread
VarHandle-> 1.普通属性原子操作 2.比反射快,直接操纵二进制码
ReentryLock->FairSync/UnFairSync->AQS
ReentrantLock lock = new ReentrantLock();
lock.lock();//调用lock接口
FairSync.java
final void lock() {
acquire(1);
}
NonfairSync.java
final void lock() {
if (compareAndSetState(0, 1))//假定原理没有锁,即status =0,尝试去锁定
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1); //请求锁
}
acquire 请求锁
AbstractQueuedSynchronizer.java
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
//在双向链表的尾巴上面新加节点
/**
* Creates and enqueues node for current thread and given mode.
*
* @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
* @return the new node
*/
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {//在双向链表的尾巴上,使用CAS锁添加节点
pred.next = node;
return node;
}
}
enq(node);
return node;
}
//对队列里面尝试获得锁
1.获取前置节点
2.前置节点是头节点,并且获取到锁
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();//获取前置节点
if (p == head && tryAcquire(arg)) {//前置节点是头节点,并且获取到锁
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
tryAcquire尝试获得锁
1.获取当前status
2.如果status=0,尝试把status更改为1,即锁定
3.如果等于当前线程,并且status>0,重入锁,更改status的值
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}