AQS源码解读

AQS源码解读
retrantlockA、B、C3个线程假设A线程lock()时候拿到了锁state被A设置成了1。static final class NonfairSync extends Sync { private static final long serialVersionUID 7316153563782823691L; /** * Performs lock. Try immediate barge, backing up to normal * acquire on failure. */ final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }此时B和C调用lock时候就会走else调用acquire(1);我们可用看见这里的B和C会尝试获取锁没有获取到就会把当前线程封装成node节点放到CLH双向队列里。让后阻断当前线程AQS的 tryAcquire()实际是调用RetrantLock的非公平nonfairTryAcquire();此时 int c getState(); c是1 并且current getExclusiveOwnerThread()条件不成立。因为此时线程A占有锁所以current此时是线程B 与 getExclusiveOwnerThread()是线程A并不相等返回false。else if (current getExclusiveOwnerThread()) { int nextc c acquires; if (nextc 0) // overflow throw new Error(Maximum lock count exceeded); setState(nextc); return true; }上面这段代码以上是假设B来了A刚好释放了锁此时突然A又来抢到了锁这个时候current就是A线程和 getExclusiveOwnerThread()也是线程A相等。又将state设置为1并且占用锁。将当前线程封装成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)) { pred.next node; return node; } } enq(node); return node; }你会发现底层调用了unsafe的接口 头指针主要是用于入队。new Node()作为头节点 第一个节点acquireQueued()干了一件什么事呢private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { int ws pred.waitStatus; if (ws Node.SIGNAL) /* * This node has already set status asking a release * to signal it, so it can safely park. */ return true; if (ws 0) { /* * Predecessor was cancelled. Skip over predecessors and * indicate retry. */ do { node.prev pred pred.prev; } while (pred.waitStatus 0); pred.next node; } else { /* * waitStatus must be 0 or PROPAGATE. Indicate that we * need a signal, but dont park yet. Caller will need to * retry to make sure it cannot acquire before parking. */ compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } return false; }没有抢到锁就阻塞LockSupport.park(this);线程挂起不会继续往下执行compareAndSetWaitStatus(pred, ws, Node.SIGNAL);unlock()f释放锁public final boolean release(int arg) { if (tryRelease(arg)) { Node h head; if (h ! null h.waitStatus ! 0) unparkSuccessor(h); return true; } return false; }释放锁实现int c getState() - releases; state的值此时是1releases值也是1 所以c就变成了0就释放了锁setExclusiveOwnerThread(null);设置当前占用线程为null就是没有线程占用。setState(c);将state状态重新设置为0.