/** * Acquires in exclusive mode, ignoring interrupts. Implemented * by invoking at least once {@link #tryAcquire}, * returning on success. Otherwise the thread is queued, possibly * repeatedly blocking and unblocking, invoking {@link * #tryAcquire} until success. This method can be used * to implement method {@link Lock#lock}. * 描述了独占的方式获取锁的流程,忽略获取锁的过程中的中断, * * @param arg the acquire argument. This value is conveyed to * {@link #tryAcquire} but is otherwise uninterpreted and * can represent anything you like. */ publicfinalvoidacquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
/** * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ protectedfinalbooleantryAcquire(int acquires) { //获取当前线程 finalThreadcurrent= Thread.currentThread(); //获取当前锁的状态,即AQS中的state属性 intc= getState(); //c==0即锁没有被占用 if (c == 0) {
/** * Acquires in exclusive uninterruptible mode for thread already in * queue. Used by condition wait methods as well as acquire. * 获取队列中已存在线程的独占不可中断模式。 * 用于条件等待方法以及获取。 * 能走到这一步,那么这个等待锁的线程所封装的节点一定在等待队列中 * * @param node the node * @param arg the acquire argument * @return {@code true} if interrupted while waiting */ finalbooleanacquireQueued(final Node node, int arg) { booleanfailed=true; try { booleaninterrupted=false; //循环,最终节点会获取到锁 for (; ; ) { //获取节点的前驱节点 finalNodep= node.predecessor(); //如果前驱节点是头节点,那么就尝试一次获取锁 if (p == head && tryAcquire(arg)) { //获取锁成功,当前节点变成了头节点,节点中的线程属性也清空。 setHead(node); // help GC p.next = null; failed = false; return interrupted; } //走到这,要么节点的前驱不是头节点,要么是获取锁失败了。 //如果前驱节点waitStatus为SIGNAL,挂起当前线程,并且检查中断 //如果前驱节点waitStatus不为SIGNAL,最终将其设置为SIGNAL if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) //在这之前,线程已经被挂起了,坐等解阻塞 interrupted = true; } } finally { if (failed) cancelAcquire(node); } } /** * Checks and updates status for a node that failed to acquire. * Returns true if thread should block. This is the main signal * control in all acquire loops. Requires that pred == node.prev. * * @param pred node's predecessor holding status * @param node the node * @return {@code true} if thread should block */ privatestaticbooleanshouldParkAfterFailedAcquire(Node pred, Node node) { // 获得前驱节点的ws intws= pred.waitStatus; //如果前驱节点是SIGNAL,返回true,就会执行挂起当前线程操作 if (ws == Node.SIGNAL) /* * This node has already set status asking a release * to signal it, so it can safely park. */ returntrue; //CANCELLED=1,所以如果ws>0,表示前驱节点已经释放锁了 if (ws > 0) { /* * Predecessor was cancelled. Skip over predecessors and * indicate retry. */ do { //1,前驱节点指向前驱节点的前驱 //2,当前节点的前驱指向前驱节点 // 即跳过取消了等待锁的前驱节点 node.prev = pred = pred.prev; } while (pred.waitStatus > 0); //新前驱节点的后继指向当前节点 pred.next = node; } else { //这种情况就直接将前驱节点的ws设置为SIGNAL /* * waitStatus must be 0 or PROPAGATE. Indicate that we * need a signal, but don't park yet. Caller will need to * retry to make sure it cannot acquire before parking. */ compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } returnfalse; } /** * Convenience method to park and then check if interrupted * * @return {@code true} if interrupted */ privatefinalbooleanparkAndCheckInterrupt() { //线程被挂起了,不会向下执行了,等待被唤醒 LockSupport.park(this); return Thread.interrupted(); }