? ?NonfairSync锁是重入锁的一种非公平锁,是指尝试获取锁的线程,如果失败则进入AQS锁等待队列中。在ReentaintLock类会默认创建一个非公平锁。
class="java"> * Creates an instance of {@code ReentrantLock}. * This is equivalent to using {@code ReentrantLock(false)}. */ public ReentrantLock() { sync = new NonfairSync(); }
/** * Sync object for non-fair locks */ 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); } }
? ?1.首先尝试将当前AQS 的state状态由0到1,如果修改成功则表明当前AQS的锁是0,没有别其他占用锁,并设置“ setExclusiveOwnerThread(Thread.currentThread());” 当前线程设置为持有锁的线程。如果设置失败则会调用AQS的 “ acquire(1);”方法。
?
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
?
?
?2. accquire(1)方法会调用尝试获得锁失败并且已经加入AQS请求队列中,则会执行线程中断,表明自己已经被加入等待队列中。AQS的tryAcquire(arg)方法会调用NonfairSync中的tryAcquire(int acquires)方法。
/** * Performs non-fair tryLock. tryAcquire is * implemented in subclasses, but both need nonfair * try for trylock method. */ 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; }
?
?
3.首先获取当前线程和当前AQS中的状态(state)。如果AQS状态为0,则尝试一次CAS操作并把当前AQS的state设置为monospace;">acquires,如果设置成功,则表明当前线程设置为持有锁的线程并返回true。
?
4.如果持有锁的线程是当前线程则将AQS状态值(state)增加acquires,设置成功则返回成功,否则返回失败表明获取锁失败。
5.addWaiter(Node mode)方法是将新建一个新的node添加到队列中,并返回此新建的节点。
/** * 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)) { pred.next = node; return node; } } enq(node); return node; }
??
? ?6.首先获取当前的队列尾部的节点,如果尾节点不为空,这将新建的节点node添加到尾部节点并执行一次CAS操作将新建的节点设置为tail节点,如果成功则将返回此进行的节点。如果失败,则,执行?enq(node);方法。
private Node enq(final Node node) { for (;;) { Node t = tail; if (t == null) { // Must initialize if (compareAndSetHead(new Node())) 8. } else { node.prev = t; if (compareAndSetTail(t, node)) { t.next = node; return t; } } } }
?
7.死循环执行 首先获取tail节点,如果tail节点为空则进行一次CAS设置header节点初始化操作。然后设置tail节点为head节点。否则将新传递的节点设置为tail节点并返回。
8.acquireQueued(addWaiter(Node.EXCLUSIVE), arg)方法
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); } }
?
9.进入方法是一个死循环 获取当前节点的前一个处理的节点,有且当前节点的前一个处理的节点是head节点并且尝试获取锁成功才返回的。设置head节点为当前节点并返回是中断状态。至此锁过程完毕。
?
二、释放锁
?
1.调用unlock方法进行释放锁实际上调用户AQS的release(arg)方法 如下:
if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; }
?2.首先会尝试释放锁,unparkSuccessor(h)方法释放成功后会将唤醒其他等待的线程node进行继续操作。
?3.执行tryRelease(arg)方法如下
protected final boolean tryRelease(int releases) { int c = getState() - releases; if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; }
? 4.首先获取AQS当前状态和要释放数量之差,判断如果当前线程不是当前锁所拥有的线程则会直接抛出异常。
? 5.如果之差为0说明完全释放成功。设置当前拥有的线程为空初始化AQS状态为0并返回true状态,否则设置AQS状态并返回false状态。
?
?
?
?
?
?
?
?
?
?