AQS4源码
@SuppressWarnings("restriction") public abstract class AbstractQueuedSynchronizer1 extends AbstractOwnableSynchronizer1 implements java.io.Serializable { private static final long serialVersionUID = 7373984972572414691L; protected AbstractQueuedSynchronizer1() {} protected final int getState() { return state; } protected final void setState(int newState) { state = newState; } static final long spinForTimeoutThreshold = 1000L; //写成员变量时候用到cas,读的时候不用cas,有可能读到之后改变了,所以写的时候就会失败。 //写成员变量都要CAS,除非是要强制修改,覆盖别人的修改。 private Node enq(final Node node) {//修改尾节点失败 for (;;) { Node t = tail; if (t == null) {//如果尾指针为null,则头指针也一定为null,表示等待队列未初始化,就CAS初始化队列。 if (compareAndSetHead(new Node()))//相当于加锁,因为不会重新获取头结点。 tail = head;//初始化头尾节点为空节点, } else {//如果尾指针非null,则队列已初始化,就CAS尝试在尾节点后插入新的节点node。 node.prev = t; if (compareAndSetTail(t, node)) {//修改尾节点为新节点(成员变量变了,局部变量没变),失败了node.prev=t也无效。 t.next = node;//for的死循环,所以不相当于加锁,因为重新获取了尾节点,里面可以多线程都进来,但是不影响。 return t; } } } } //mode:Node.EXCLUSIVE独占, Node.SHARED共享的。 private Node addWaiter(Node mode) { // 构造节点,mode有两种:EXCLUSIVE(独占)和SHARED(共享) Node node = new Node(Thread.currentThread(), mode);//多个线程在排队,一个线程附在一个Node节点, Node pred = tail; if (pred != null) {//尾节点不为null,其实被enq(node)重复了。 node.prev = pred; if (compareAndSetTail(pred, node)) {//修改共享变量cas, 成员变量变了,局部变量没变。失败node.prev=pred无效。 pred.next = node;//里面可以多线程都进来,但是不影响。因为pred=tail=新的节点node,重新获取了尾节点。 return node;//返回新尾节点 } } enq(node);//修改尾节点失败。自旋的方式继续加入等待队列。 return node;//返回新尾节点 } //将队列的头设置为节点,从而使其出列。仅由Acquire方法调用。为了GC,还可以空出未使用的字段,并抑制不必要的信号和遍历。 private void setHead(Node node) { head = node; node.thread = null; node.prev = null; } //node可能是head节点可能是失效节点。 private void unparkSuccessor(Node node) { int ws = node.waitStatus; if (ws < 0)//-1就设置为0,异常节点这里是1。 头结点要么是0要么是-1。头结点设置为0. compareAndSetWaitStatus(node, ws, 0); /*head下一个节点,从头结点开始一个个的找后继,直到把队列找完。 next节点是正常的就找next,next不是正常的,就不能再找next,因为next.next有可能是自己。 就tail往前找,从tail往前找prev一定能够吧所有正常节点找到(还会找到不正常的节点)。 如果找到的这个节点status<=0,然后唤醒,但是这个节点异常了只是状态没有修改过来, 那么唤醒的这个假正常节点就不会去获取锁,而是帮着正常节点做 ,做完退出。 */ Node s = node.next;//node=head,head.next不一定是初始节点,可能被改过指向曾经正常的一个节点,这个节点现在正常与否未知。 //下一个节点s被取消,node还没来得及重新设置新的正常后继节点。队列还没有处于稳定状态。 //第一个节点被取消,就从后往前找下一个状态正常节点。也相当于是head后面第一个status正常节点。 if (s == null || s.waitStatus > 0) { s = null; for (Node t = tail; t != null && t != node; t = t.prev) //右边的正常节点。 if (t.waitStatus <= 0)// 0/-1都唤醒 s = t; } if (s != null)//s可能=head,head.thread=null就什么都不做。 LockSupport.unpark(s.thread); } private void doReleaseShared() {// 读锁释放(共享锁),这个方法只会唤醒一个节点 for (;;) { Node h = head; if (h != null && h != tail) { int ws = h.waitStatus; if (ws == Node.SIGNAL) {//-1, 如果头节点状态为SIGNAL,说明要唤醒下一个节点,并且设置0成功就唤醒下一个, if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))//设置为0成功(没有异常)就去unparkSuccessor,设置为0失败就跳过unparkSuccessor再次从head开始, continue; unparkSuccessor(h);//唤醒下一个节点 //等于0 并且 设置-3失败,就跳过, 把头节点的状态改为PROPAGATE成功才会跳到下面的if } else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) continue; // } if (h == head) // head变化了,继续唤醒head, break;//头结点变了,head后面节点自行出队了, } } private void setHeadAndPropagate(Node node, int propagate) { Node h = head; setHead(node); // 如果旧的头节点或新的头节点为空或者其等待状态小于0(表示状态为SIGNAL/PROPAGATE) if (propagate > 0 || h == null || h.waitStatus < 0 || (h = head) == null || h.waitStatus < 0) { Node s = node.next;//node下一个节点,需要传播 if (s == null || s.isShared()) // 如果下一个节点为空,或者是需要获取读锁的节点 doReleaseShared();//唤醒head下一个节点 //一个节点A获取了读锁后,会唤醒下一个读节点B,这时候B也会获取读锁,然后B继续唤醒C,依次往复, //也就是说这里的节点是一个唤醒一个这样的形式,而不是一个节点获取了读锁后一次性唤醒后面所有的读节点。 } } /* 所看到的所有成员变量都在工作内存里面,局部变量更在工作内存里面。 */ //有可能是0变到1,也有可能是-1变到1, private void cancelAcquire(Node node) { if (node == null) return; node.thread = null;//异常节点,thread先清空, /*失效节点:不断改变自己的前驱 在改变status 最后改变next*/ Node pred = node.prev;//node就是头结点,pred就是null, while (pred.waitStatus > 0)//找到新的-1/0,跳过已经取消的节点。 node.prev = pred = pred.prev;//断开node.prev。node.prev只有节点自己线程修改不用cas, //while出来时候pred=0/-1,while之后pred可能变为1。 0/-1节点在任何时候都有可能变为1,每次判断都只是瞬间的值。 /*pred = pred.prev;不是改变属性 node.prev = pred是改变属性*/ Node predNext = pred.next;//此时pred可能是0/-1节点也可能是1节点. /* 节点异常了只能通过status和thread看得出来。否则外界不知道异常了。别人也是通过status来看这个节点是不是异常了,所以有延时。 */ node.waitStatus = Node.CANCELLED;//强制覆盖,不用cas,以这个为主。 //修改队列。去掉的节点是尾节点就要修改,尾节点就不需要prev.next了。 if (node == tail && compareAndSetTail(node, pred)) {//死循环的cas会重来,一次cas失败了就放弃让别人去做,优先级低于直接赋值。 //修改tail为pred,修改失败:不是尾节点了,加进来了新的节点。 //pred.next!=predNext就是有节点加进来了,并且pred.next=新的节点,就不置位null。 compareAndSetNext(pred, predNext, null);//tail的next置位null,GC } else {//不是尾节点,或者是尾节点但是加进来了新的节点, int ws; if (pred != head //node前面是head,就不要去设置后继关系,而是唤醒, && /* 再次判断pred的状态是正常=0/-1 有可能这时候prev=head,并且有可能head=0已经出队了,pred.thread = null就要唤醒node后面*/ /*prev不是头结点并且异常了,如果不管了,如果后面正常节点阻塞了,并且前面没有正常节点 那么head=0 unlock出队失败时候,队列里面的就全阻塞了,就永远不能出队。*/ ( (ws = pred.waitStatus) == Node.SIGNAL|| ( ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL) ) ) && pred.thread != null ) { //pred不是头节点,并且,pred正常 //有可能这时候prev=head,但是head=-1,可以正常唤醒。 Node next = node.next; if (next != null && next.waitStatus <= 0)//next节点也可能是取消了。 //pred.next没有被修改。next不可能为null,因为线程退出了节点可能还在, compareAndSetNext(pred, predNext, next);//把node也跳过,失败不重来,因为别的正常-1节点也会修改,让正常节点。 } else {//node.prev=head,ndoe异常, //node不一定是紧挨着head的节点,正常节点在node后面并且在第一个栅栏里面, //如果这里不唤醒,只是依靠unlock唤醒,但是unlock在head=0时候是不会唤醒的什么都不做的,unlock在这种情况不负责唤醒线程获取锁, //那么就该第一个栅栏里面的正常节点去获取锁,防止正常节点阻塞了,这里就要去唤醒,否则unlock出队失败就永远不能唤醒。 //或者,node不是第一个节点但是prev状态值=1了,或者,node不是第一个节点prev状态值=0/-1但是prev的thread=null了 unparkSuccessor(node);//唤醒node这个异常节点的后面节点 } node.next = node; // help GC。断开node.next } } //前驱节点是-1就阻塞。前驱节点是0就是初始化设置为-1,并且清理失效的节点。直到找到-1为止。 private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { //第一次进来,pred.waitStatus=默认值0,然后设置=-1,parkAndCheckInterrupt()失败会再次进来,直接返回true,表示应该阻塞。 //第一次进来不阻塞,第二次进来阻塞。 int ws = pred.waitStatus;//0 1 -1 -2 -3。 //前驱=-1,当前节点node应该阻塞。SIGNAL表示释放后需要唤醒后继节点。 if (ws == Node.SIGNAL)//这一行pred=-1,下一行pred可能会变为1, return true; //其余返回false,当前节点不应该阻塞。 //清理失效的节点,并把新的前驱节点设置为-1。跳过现在是1的,并且是1之后不会变回-1。 if (ws > 0) {//waitStatus = 1,清理CACELLED节点。 do { node.prev = pred = pred.prev;//pred往前进一个, } while (pred.waitStatus > 0);//<=0作为边界 pred.next = node;//回指肯定成功。 直接赋值覆盖cas赋值。 } else {//0或者-3 -2,是1不会变为-1。就是前驱后继关系。 //ws此时=0/-3/-2就说明没有取消就设置为-1,ws=1说明取消了,不能设置为-1。 /* 再次判断pred的状态为正常=0 */ compareAndSetWaitStatus(pred, ws, Node.SIGNAL);//设置新的前驱waitStatus=-1,有可能失败。被自己改为了1就以1为主,这边失败算了。 //有可能马上被设置为1,即使cas了也不保证cas下一行状态没改变,只是保证获取ws到改变期间没有变化,这一行之后变化了不管。 } /*找前驱节点:不断改变自己的前驱 在改变找到节点的next 最后修改找到节点的status*/ return false; } static void selfInterrupt() { //线程被打上中断标记。但是线程正常执行,只有判断是否中断然后return线程才会停止。否则跟没有中断是一样的。 Thread.currentThread().interrupt(); } private final boolean parkAndCheckInterrupt() throws InterruptedException {//阻塞并看阻塞是否成功 Thread t = Thread.currentThread(); if(t.getName().equals("") ) { throw new InterruptedException(); } LockSupport.park(this);//阻塞,this=ReentrantLock对象。直到被唤醒或者中断。 return Thread.interrupted();//唤醒时候,中断唤醒返回true,interrupted=true,获取到锁(设置了成员属性的值)之后还是会中断。并复位, } //返回true当前线程就阻塞(就没有获取锁),返回false就不阻塞(就获取了锁)。一次只能一个线程执行(exclusiveOwnerThread=的线程执行),其余阻塞 // 节点加进去之后,就死循环(死循环也是在最前面才获取锁,否则死循环或者阻塞), final boolean acquireQueued(final Node node, int arg) throws InterruptedException { boolean failed = true; try { boolean interrupted = false; //旋转1次,旋转2次,旋转3次,或者多次阻塞,compareAndSetWaitStatus(pred, ws, Node.SIGNAL)有可能一直失败,多次在于这里。 for (;;) { final Node p = node.predecessor(); //是最前面的节点(节点从前到后依次获取锁),并且获取锁成功,就不阻塞,这个节点退出链表,更新链表,Lock方法返回。 if (p == head && tryAcquire(arg)) {//否则死循环(自旋出队)。获取锁的线程只有一个,所以这里是加锁。tryAcquire方法在Write锁里面会重写 //setHead()加锁了不用CAS(只有修改成员变量cas否则都是线程的局部内部变量)。 //head=node,node.thread=null,node.prev=null。thread就是调用这个函数的线程设置为null(已经获取了锁就移除这个节点)。 //head指向正在运行的线程的节点,就是不在排队中的节点的线程。 如果不在队列的线程获取了锁,head不变继续指向。 //如果队列中的线程获取了锁,head就指向新的获取锁的线程的节点。 setHead(node);//node变成空节点并升级为头节点。 status=0/-1没变。 p.next = null; // help GC,node变为头结点,head节点gc, // if(Thread.currentThread().getName().equals("1号窗口") ) { // throw new InterruptedException(); // } failed = false;//不走cancelAcquire(node), // if(Thread.currentThread().getName().equals("1号窗口") ) { // throw new InterruptedException(); // } return interrupted;//已经获取了锁,就不用中断了,lock方法返回void,不用阻塞了。先执行finally再return。 } //不是最前面的节点,或者 是最前面的节点但是获取锁失败。判断当前线程是否需要阻塞。 //shouldParkAfterFailedAcquire()判断当前线程是否需要阻塞 (通过前驱节点判断) //parkAndCheckInterrupt()阻塞当前线程 ,阻塞失败继续死循环。 if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true;//如果状态为true说明发生过中断,会补发一次中断,中断唤醒的线程应该去中断而不是继续执行,即调用interrupt()方法 } } finally {//不异常也走这里然后return, if (failed)//node成为了头节点异常,线程退出,head节点还在, //抛出任何异常,则取消任务。这里不catch,外层函数要catch,否则异常一直在。 cancelAcquire(node); } } //这个线程能够响应中断,即中断线程的等待状态 private void doAcquireInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.EXCLUSIVE);//添加一个独占的节点, boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC failed = false; return; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) throw new InterruptedException();//线程中断唤醒抛出异常 } } finally { if (failed) cancelAcquire(node); } } private boolean doAcquireNanos(int arg, long nanosTimeout) throws InterruptedException { if (nanosTimeout <= 0L) return false; final long deadline = System.nanoTime() + nanosTimeout;//获取截止时间点 final Node node = addWaiter(Node.EXCLUSIVE);//节点模式是独占的 boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC failed = false; return true; } nanosTimeout = deadline - System.nanoTime();//截止时间过了没有 if (nanosTimeout <= 0L)// 超过时间,依然获取不到,则返回false;否则返回true return false; //不会一直阻塞等待唤醒,只会阻塞一定时间, if (shouldParkAfterFailedAcquire(p, node) && nanosTimeout > spinForTimeoutThreshold) LockSupport.parkNanos(this, nanosTimeout);//阻塞剩余的时间 if (Thread.interrupted())// 等待过程中,可以被中断,中断就抛异常,不像别的中断后继续运行,只是设置中断标记,然后我们自己去处理。 throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } } //ReadLock获取锁走这个方法,AQS排队, private void doAcquireShared(int arg) throws InterruptedException { final Node node = addWaiter(Node.SHARED);//ReadLock节点是共享模式,nextWaiter是一个空节点(共享模式是null【ReentrantLock和WriteLock】) boolean failed = true; try { boolean interrupted = false; for (;;) {//自旋 final Node p = node.predecessor(); if (p == head) {//是第一个节点。获取锁 int r = tryAcquireShared(arg);//尝试获取锁,返回-1获取锁失败,返回1获取锁成功。 if (r >= 0) {//获取成功, // 头节点后移并传播。传播即唤醒后面连续的读节点 setHeadAndPropagate(node, r);//node变为头结点 p.next = null; // help p GC if (interrupted)//中断唤醒在获取的锁 selfInterrupt();//设置中断标记 failed = false; return; } } //设置前面-1然后阻塞, if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally {//不异常也走这里 if (failed) cancelAcquire(node);//异常设置自己=1,并帮助清理AQS的异常节点,建立后驱或者唤醒后面节点 } } private void doAcquireSharedInterruptibly(int arg) throws InterruptedException {//Semaphore排队,多线程 final Node node = addWaiter(Node.SHARED);//共享节点,Semaphore可以多线程进入,所以跟读锁是一样的, boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg);//获取许可,返回减1后的许可 if (r >= 0) { setHeadAndPropagate(node, r);//r=0,说明没有许可,就不会去唤醒下一个节点 p.next = null; // help GC failed = false; return; } } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } } /** 以共享定时模式获取 */ private boolean doAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException { if (nanosTimeout <= 0L) return false; final long deadline = System.nanoTime() + nanosTimeout; final Node node = addWaiter(Node.SHARED); boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg); if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC failed = false; return true; } } nanosTimeout = deadline - System.nanoTime(); if (nanosTimeout <= 0L) return false; if (shouldParkAfterFailedAcquire(p, node) && nanosTimeout > spinForTimeoutThreshold) LockSupport.parkNanos(this, nanosTimeout); if (Thread.interrupted()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } } protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); } protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); } protected int tryAcquireShared(int arg) { throw new UnsupportedOperationException(); } protected boolean tryReleaseShared(int arg) { throw new UnsupportedOperationException(); } protected boolean isHeldExclusively() { throw new UnsupportedOperationException(); } //ReentrantLock和WriteLock获取锁,走这个方法,tryAcquire在ReentrantReadWrite里面有重写 public final void acquire(int arg) throws InterruptedException {//tryAcquire会先去获取锁,获取成功返回true否则false。 //addWaiter()穿建一个独占的节点添加到尾节点去。 //如果获取失败,则向等待队列中添加一个独占模式的节点,并通过acquireQueued()阻塞的等待该节点被调用(即当前线程被唤醒)。 //如果是因为被中断而唤醒的,则复现中断信号。 //acquireQueued()检查node的前继节点是否是头节点。如果是,则尝试获取锁;如果不是,或是但获取所失败,都会尝试阻塞等待。 //addWaiter时候线程异常了,不会吧head置为1. if (!tryAcquire(arg) && //返回是否中断,如果返回中断,则调用当前线程的interrupt()方法 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt();//interrupted = true当前线程中断执行。重放acquireQueued里面的中断。 } //跟acquire差不多 public final void acquireInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted())//线程中断标志为1 throw new InterruptedException();//线程中断抛出异常 if (!tryAcquire(arg))//获取一次锁 doAcquireInterruptibly(arg); } public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); return tryAcquire(arg) || doAcquireNanos(arg, nanosTimeout); } public final boolean release(int arg) {//只有一个线程访问 if (tryRelease(arg)) {//true就表示OwnerThread=null了state=0了,减少state和OwnerThread。 //tryRelease()返回true表示已完全释放,可唤醒所有阻塞线程;否则没有完全释放,不需要唤醒。这个线程要再次unlock才去唤醒队列的节点。 Node h = head; //头结点只能是0/-1不可能是1。头结点由第一个入队节点创建,第一个入队节点线程异常了也只会设置第一个节点=1,不会影响到头结点,不会设置到头结点=1。 //头结点看成一直是正常节点, if (h != null && h.waitStatus != 0) unparkSuccessor(h);//head.waitStatus=-1才进来,唤醒head的后继 //h=null,头结点都还没有建立,队列也还没有建立。 /*或者h!=null&&head.waitStatus==0, 最近的正常节点不一定是紧挨着的节点,最近的正常节点中间可能还有异常节点。 head.waitStatus变成-1是由head后面的最近正常节点设置的(不一定是紧挨着的节点),说明曾经有一个正常节点执行完了3步,这个正常节点是否还正常未知。 head.waitStatus==0说明head后面都异常了,或者后面第一个正常节点(不一定是紧挨着的节点)还没有自旋到这一步,还没被阻塞 。说明没有曾经一个正常节点完成了3步,把他设置成-1。 如果head后面的正常节点都阻塞了(仅仅只需要看最近的正常节点),必然会设置head=-1,并且是由最近正常节点设置的。 */ //lock时候head.waitStatus==0不出对,说明都不做,head不改变。唤醒时候head不变,只有获取到锁之后,head变化。 return true; } return false;//unlock就不会去唤醒等待的第一个节点 } //ReadLock获取锁走这个方法,tryAcquireShared在ReentrantReadWrite里面,doAcquireShared在AQS里面, public final void acquireShared(int arg) throws InterruptedException { if (tryAcquireShared(arg) < 0)//获取共享锁,读锁,获取失败,排队。 doAcquireShared(arg);//排队 } public final void acquireSharedInterruptibly(int arg) throws InterruptedException {//Semaphore获取一个许可 if (Thread.interrupted()) throw new InterruptedException(); if (tryAcquireShared(arg) < 0)//Semaphore获取一个许可,有许可只是没有获取到,就死循环获取许可, doAcquireSharedInterruptibly(arg);//只有在许可没了才去排队,Semaphore排队 } public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); return tryAcquireShared(arg) >= 0 || doAcquireSharedNanos(arg, nanosTimeout); } public final boolean releaseShared(int arg) {// 读锁释放(共享锁),多线程访问 if (tryReleaseShared(arg)) {//释放锁,释放之后state=0返回true。读锁全部释放完了,才会去唤醒AQS doReleaseShared();//唤醒head下一个 return true; } return false; } public final boolean hasQueuedThreads() { return head != tail; } public final boolean hasContended() { return head != null; } public final Thread getFirstQueuedThread() { //前面是快速失败 return (head == tail) ? null : fullGetFirstQueuedThread(); } private Thread fullGetFirstQueuedThread() { /* 第一个节点通常是head.next,尝试获取其线程字段,确保一致的读取: 如果线程字段为空或s.prev不再是head,我们试了2次。 */ Node h, s; Thread st; if (((h = head) != null && (s = h.next) != null && s.prev == head && (st = s.thread) != null) || ((h = head) != null && (s = h.next) != null && s.prev == head && (st = s.thread) != null)) return st; Node t = tail; Thread firstThread = null; while (t != null && t != head) { Thread tt = t.thread; if (tt != null) firstThread = tt; t = t.prev; } return firstThread; } public final boolean isQueued(Thread thread) { if (thread == null) throw new NullPointerException(); for (Node p = tail; p != null; p = p.prev) if (p.thread == thread) return true; return false; } //第一个节点线程部位null并且不是共享的读锁 protected final boolean apparentlyFirstQueuedIsExclusive() { Node h, s; return (h = head) != null && (s = h.next) != null && !s.isShared() && s.thread != null; } //h=t有可能是指向同一个,有可能都是null。h!=t有可能指向不同的,有可能head!=null但tail=null。 //注意;一个节点变成null只能通过GC,有人指向就不会GC变成null,没有主动置为null的语句。中间节点的next不可能指向一个null,next指向的节点有人指向不会被GC,也没有主动设置为null的语句, /*队列的状态:1(false,获取锁)head tail都是null 2(true,排队)head!=null tail=null,head的next和prev都=null,有人在初始化队列, 3(false,获取锁,此时有线程正在入队,不准确)head=tail!=null,但是next和prev都是null 4(false,获取锁)有第一个节点是当前线程,head tail都!=null,head.next=tail tail.next=null 5(true,排队)有第一个节点不是当前线程,head tail都!=null,head.next=tail tail.next=null */ //h!=t && h.next=null,那么tail就等于null还没有初始化,head!=null。 public final boolean hasQueuedPredecessors() { Node t = tail; Node h = head; Node s; /* 公平原则:没人占用锁时候,要不要去获取锁。有线程在队列里面,说明那些是获取锁失败的才去排队。没有线程获取锁,线程是第一个节点获取锁,第一个节点不是当前线程排队。 当然这个不一定准确:有可能别的线程已经开始排队了,只是没有完全加入到队列,另一个线程过来还是可以立马获取锁。但是单单只看第一个节点存不存在,也不准确。 */ //返回true排队,true&&(true||)。true&&(false||true)。有第一个节点不是当前线程,或者 ,有别人在初始化队列,. //返回fasle获取锁: false。true&&(false||false):对裂空没有线程,有第一个节点是当前线程 return h != t && ((s = h.next) == null || s.thread != Thread.currentThread()); //h!=t&&h.next=null 或者 h!=t&&h.next.thread!=currentThread() 返回true排队。否则获取锁。 // 有人在初始化 或者 有第一个节点不是当前线程。 } public final int getQueueLength() {//不是线程安全 int n = 0; for (Node p = tail; p != null; p = p.prev) { if (p.thread != null) ++n; } return n; } public final Collection<Thread> getQueuedThreads() {//不是线程安全 ArrayList<Thread> list = new ArrayList<Thread>(); for (Node p = tail; p != null; p = p.prev) { Thread t = p.thread; if (t != null) list.add(t); } return list; } public final Collection<Thread> getExclusiveQueuedThreads() {//不是线程安全 ArrayList<Thread> list = new ArrayList<Thread>(); for (Node p = tail; p != null; p = p.prev) { if (!p.isShared()) { Thread t = p.thread; if (t != null) list.add(t); } } return list; } public final Collection<Thread> getSharedQueuedThreads() {//不是线程安全 ArrayList<Thread> list = new ArrayList<Thread>(); for (Node p = tail; p != null; p = p.prev) { if (p.isShared()) { Thread t = p.thread; if (t != null) list.add(t); } } return list; } public String toString() { int s = getState(); String q = hasQueuedThreads() ? "non" : ""; return super.toString() + "[State = " + s + ", " + q + "empty queue]"; } final boolean isOnSyncQueue(Node node) { //=-2就是不在AQS的同步队列,在condition的等待队列, prev=null肯定不在AQS,便说明节点还在Condition队列中 if (node.waitStatus == Node.CONDITION || node.prev == null) return false; // 说明当前Node的状态不是CONDITION,同时它既有prev节点也有next节点,那么说明它在AQS队列里 if (node.next != null) return true; return findNodeFromTail(node);//node在不在AQS同步队列中 } private boolean findNodeFromTail(Node node) {//node在不在AQS同步队列中 Node t = tail;//从tail往前可以找到所有AQS的节点 for (;;) { if (t == node) return true; if (t == null) return false; t = t.prev; } } final boolean transferForSignal(Node node) { //唤醒从-2变成0,condition加到AQS時候狀態是0,唤醒失败就是=1,await里面唤醒AQS时候异常了,设置为1了,就去唤醒下一个, //此时他不移到AQS继续放到condition队列,不是-2就表示已经加入到队列去了, if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) return false; Node p = enq(node);//把节点加到AQS队列,直接把condition節點全部拿過來,屬性值=-2不變,返回AQS尾节点就是前面一个节点 int ws = p.waitStatus; if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))//AQS前面节点异常了,或者设置-1失败了,就唤醒自己,防止自己在AQS上的时候不能够唤醒去获取锁。 LockSupport.unpark(node.thread);//node移到AQS唤醒并且return true, //ws<=0&&compareAndSetWaitStatus(p,ws,-1)成功,node移到AQS不唤醒并且return true。 return true; } //中断唤醒时候=-2没有开始加入AQS返回-1,=0开始加入AQS返回1, final boolean transferAfterCancelledWait(Node node) { //中断唤醒,但是!=-2,说明还没有signal(有可能signal了只是还没有改变状态),還沒有加入隊列,幫助加入AQS隊列, if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) { enq(node); return true; } //不是-2已经设置为0了,已经signal了改变状态=0了,只是没有执行到加入到队列这行,等待signal线程加入到AQS队列, while (!isOnSyncQueue(node))//不在AQS队列就让步。等著加到AQS去 Thread.yield(); return false; } final int fullyRelease(Node node) { boolean failed = true; try { int savedState = getState();//Sync的state //unlock调用release(1),这里全部释放。 if (release(savedState)) {//通过head唤醒AQS队列中下一个节点。state变成0。release成功返回true没有唤醒成功返回false failed = false; return savedState; } else { throw new IllegalMonitorStateException(); } } finally { if (failed)//release(savedState)异常了,就设置condition队列中的自己=1, node.waitStatus = Node.CANCELLED;//出现异常=1 } } public final boolean owns(ConditionObject condition) { return condition.isOwnedBy(this); } public final boolean hasWaiters(ConditionObject condition) {//不是线程安全 if (!owns(condition)) throw new IllegalArgumentException("Not owner"); return condition.hasWaiters(); } public final int getWaitQueueLength(ConditionObject condition) {//不是线程安全 if (!owns(condition)) throw new IllegalArgumentException("Not owner"); return condition.getWaitQueueLength(); } public final Collection<Thread> getWaitingThreads(ConditionObject condition) {//不是线程安全 if (!owns(condition)) throw new IllegalArgumentException("Not owner"); return condition.getWaitingThreads(); } //内部类,可以使用外部类的方法和属性 public class ConditionObject implements Condition, java.io.Serializable { private static final long serialVersionUID = 1173984872572414699L; private transient Node firstWaiter;//Condition的等待队列的头尾。AQS有一个队列,Condition有一个队列。 private transient Node lastWaiter; public ConditionObject() {} private Node addConditionWaiter() { //Condition对队列的操作没考虑并发,因为对应的操作都是在线程获得锁之后才进行的 Node t = lastWaiter; //尾节点!=-2就清除,Condition里面的节点状态只能是0和-2,否则就是无效节点 if (t != null && t.waitStatus != Node.CONDITION) {//=1, unlinkCancelledWaiters(); t = lastWaiter; } //创建新的节点放到Condition队列,移除AQS节点。 //AQS节点prev!=null,next只有最后一个=null。 //Condition节点,prev=next=null,nextWaiter只有最有一个=null。 Node node = new Node(Thread.currentThread(), Node.CONDITION); if (t == null) firstWaiter = node; else t.nextWaiter = node; lastWaiter = node; return node; } // private void doSignal(Node first) { do { if ((firstWaiter = first.nextWaiter) == null)//只有一个,并且移除了,就都是null。 lastWaiter = null; first.nextWaiter = null;//把nextWaiter置为了null, //把condition的第一個移到AQS去,不一定喚醒線程, } while (!transferForSignal(first) && (first = firstWaiter) != null); } //condition隊列移到AQS隊列, private void doSignalAll(Node first) { lastWaiter = firstWaiter = null; do { Node next = first.nextWaiter; first.nextWaiter = null; transferForSignal(first); first = next; } while (first != null); } //从第一个到最后一个,清除无效!=-2的节点。单向链表。 private void unlinkCancelledWaiters() { Node t = firstWaiter; Node trail = null; while (t != null) { Node next = t.nextWaiter; if (t.waitStatus != Node.CONDITION) { t.nextWaiter = null; if (trail == null) firstWaiter = next; else trail.nextWaiter = next; if (next == null) lastWaiter = trail; } else trail = t; t = next; } } //唤醒Condition队列第一个非CANCELLED节点。 public final void signal() { if (!isHeldExclusively())//获得锁的线程是不是当前线程,当前线程没有获取锁, throw new IllegalMonitorStateException(); Node first = firstWaiter; if (first != null) doSignal(first); } //condition全部移到AQS public final void signalAll() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); Node first = firstWaiter; if (first != null) doSignalAll(first); } //当前线程进入等待状态直到被通知,在此过程中对中断信号不敏感,不支持中断当前线程 public final void awaitUninterruptibly() { Node node = addConditionWaiter(); int savedState = fullyRelease(node); boolean interrupted = false; while (!isOnSyncQueue(node)) { LockSupport.park(this); if (Thread.interrupted())//和await()区别是线程中断不会退出循环 interrupted = true; } try { //恢复之前的锁状态并相应中断 if (acquireQueued(node, savedState) || interrupted) selfInterrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } private static final int REINTERRUPT = 1;//线程在等待过程中发生了中断,但不需要抛出异常 private static final int THROW_IE = -1;//线程在等待过程中发生了中断,且需要抛出异常 //没有中断返回0,中断返回-1说明中断时候没有调用signal抛出异常,返回1说明中断时候调用了signal设置自己中断标记。 private int checkInterruptWhileWaiting(Node node) { return Thread.interrupted() ? (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) : 0; } private void reportInterruptAfterWait(int interruptMode) throws InterruptedException { if (interruptMode == THROW_IE) throw new InterruptedException(); else if (interruptMode == REINTERRUPT) selfInterrupt(); } //当前获取lock的线程进入到等待队列。 只有获取锁的线程才进来,单线程的。 public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); //将当前线程包装成Node(只要了線程屬性,其餘屬性沒要),尾插入到Condition等待队列中, Node node = addConditionWaiter(); //释放锁,设置state=0,清空owenerThread,唤醒AQS, //记录之前的state,唤醒后需要恢复状态,后续unlock()也要unlock这么多次不然将报错。 //线程从lock开始到这一行,都是要获取锁的,所以是线程安全的,。 int savedState = fullyRelease(node); //await开始一直到上面一行,都是线程安全的,下面就不线程安全了。 int interruptMode = 0; while (!isOnSyncQueue(node)) {//当前节点到AQS队列之后就退出while循环,唤醒时候有可能不在AQS队列上就阻塞直到在AQS队列上。 LockSupport.park(this);//当前线程在condition上阻塞,等著移到AQS,然後在AQS隊列裡面喚醒。喚醒時候已經在AQS隊列裡面了。 /* 如果是中断唤醒,发生时期是任意的。可能在condition里面可能在AQS里面 */ //中断唤醒,不是AQS的head唤醒,有可能还不在AQS队列里面。checkInterruptWhileWaiting会帮助加入队列, if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)//等于0就不是中断唤醒,=-1抛出异常 =1设置中断标记 //没有开始加入AQS返回-1,=0开始加入AQS返回1, break;//中断唤醒就跳出while,正常唤醒就继续while看是不是在AQS队列 } //在AQS队列上唤醒,尝试获取AQS的鎖,可能会再次在AQS上阻塞,恢复await前的状态savedState, if (acquireQueued(node, savedState) && interruptMode != THROW_IE)//-1 //AQS唤醒了,获取到锁了, //后面代码又是线程安全的。 interruptMode = REINTERRUPT; if (node.nextWaiter != null) // 清除ConditioN队列中 != -2 的节点 unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode);//-1就抛出异常,1就设置自己中断标记。 } public final long awaitNanos(long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter();//加入Condition队列 int savedState = fullyRelease(node);//释放锁 final long deadline = System.nanoTime() + nanosTimeout;//过期时间点 int interruptMode = 0; while (!isOnSyncQueue(node)) { if (nanosTimeout <= 0L) { transferAfterCancelledWait(node);//加入队列 break; } if (nanosTimeout >= spinForTimeoutThreshold) LockSupport.parkNanos(this, nanosTimeout); //判断线程是否被中断 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; nanosTimeout = deadline - System.nanoTime(); } //响应中断 if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); return deadline - System.nanoTime();//返回耗时 } public final boolean awaitUntil(Date deadline) throws InterruptedException { long abstime = deadline.getTime(); if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); boolean timedout = false; int interruptMode = 0; while (!isOnSyncQueue(node)) { if (System.currentTimeMillis() > abstime) { timedout = transferAfterCancelledWait(node); break; } LockSupport.parkUntil(this, abstime); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); return !timedout; } public final boolean await(long time, TimeUnit unit) throws InterruptedException { long nanosTimeout = unit.toNanos(time); if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); final long deadline = System.nanoTime() + nanosTimeout; boolean timedout = false; int interruptMode = 0; while (!isOnSyncQueue(node)) { if (nanosTimeout <= 0L) { timedout = transferAfterCancelledWait(node); break; } if (nanosTimeout >= spinForTimeoutThreshold) LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; nanosTimeout = deadline - System.nanoTime(); } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); return !timedout; } //判断Condition是否属于sync. final boolean isOwnedBy(AbstractQueuedSynchronizer1 sync) { return sync == AbstractQueuedSynchronizer1.this; } protected final boolean hasWaiters() {//不是线程安全 if (!isHeldExclusively()) throw new IllegalMonitorStateException(); for (Node w = firstWaiter; w != null; w = w.nextWaiter) { if (w.waitStatus == Node.CONDITION) return true; } return false; } protected final int getWaitQueueLength() {//不是线程安全 if (!isHeldExclusively()) throw new IllegalMonitorStateException(); int n = 0; for (Node w = firstWaiter; w != null; w = w.nextWaiter) { if (w.waitStatus == Node.CONDITION) ++n; } return n; } protected final Collection<Thread> getWaitingThreads() {//不是线程安全 if (!isHeldExclusively()) throw new IllegalMonitorStateException(); ArrayList<Thread> list = new ArrayList<Thread>(); for (Node w = firstWaiter; w != null; w = w.nextWaiter) { if (w.waitStatus == Node.CONDITION) { Thread t = w.thread; if (t != null) list.add(t); } } return list; } } static final class Node { //节点是共享节点 static final Node SHARED = new Node(); // 节点是独占节点 static final Node EXCLUSIVE = null; //由于超时或中断,此节点被取消。 static final int CANCELLED = 1; //-1,唤醒,这个节点成为head结点时候,unlock会去通过head唤醒后继节点 static final int SIGNAL = -1; //表示当前节点在等待condition,即在condition队列中; static final int CONDITION = -2; //表示releaseShared需要被传播给后续节点(仅在共享模式下使用); static final int PROPAGATE = -3; volatile int waitStatus;//默认0, //前继节点; volatile Node prev; //后继节点; volatile Node next; //当前线程。 volatile Thread thread; //condition节点的属性,ReentrantLock时候nextWaiter=null, Node nextWaiter; final boolean isShared() { return nextWaiter == SHARED; } final Node predecessor() throws NullPointerException { Node p = prev; if (p == null) throw new NullPointerException(); else return p; } Node() { // Used to establish initial head or SHARED marker this.name = "头结点"; } volatile String name; Node(Thread thread, Node mode) { //用于锁 this.nextWaiter = mode;//独占锁的nextWaiter是模式=Node.EXCLUSIVE=null, this.thread = thread; this.name = this.thread.getName(); } Node(Thread thread, int waitStatus) { //用于Condition this.waitStatus = waitStatus; this.thread = thread; this.name = this.thread.getName(); } public String toString() { return "name:"+this.name+",prev:" + prev.name + ",next:" + next.name; } } //head指向获取锁的线程的节点,仅仅保存next结点的引用。。如果是没有入队的线程获取锁,head不变。head节点是一个哨兵节点 ,头结点不存储Thread,仅 private transient volatile Node head; private transient volatile Node tail;//tail指向链表的最后一个节点 //如果没有记录重入次数,则第一次释放锁时,会一次性把ownerThread多次重入的锁都释放掉,而此时“锁中的代码”还没有执行完成,造成混乱。 private volatile int state;//所有者线程已经重复获取该锁的次数,每次加1。 private static Unsafe unsafe; private static final long stateOffset;//state private static final long headOffset;//head private static final long tailOffset;//tail private static final long waitStatusOffset;//Node.waitStatus private static final long nextOffset;//Node.next static { try { unsafe = java.security.AccessController .doPrivileged(new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() { public sun.misc.Unsafe run() throws Exception { Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class; for (java.lang.reflect.Field f : k.getDeclaredFields()) { f.setAccessible(true); Object x = f.get(null); if (k.isInstance(x)) return k.cast(x); } throw new NoSuchFieldError("the Unsafe"); } }); stateOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer1.class.getDeclaredField("state")); headOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer1.class.getDeclaredField("head")); tailOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer1.class.getDeclaredField("tail")); waitStatusOffset = unsafe.objectFieldOffset(Node.class.getDeclaredField("waitStatus")); nextOffset = unsafe.objectFieldOffset(Node.class.getDeclaredField("next")); } catch (Exception ex) { throw new Error(ex); } } protected final boolean compareAndSetState(int expect, int update) { return unsafe.compareAndSwapInt(this, stateOffset, expect, update); } private final boolean compareAndSetHead(Node update) { return unsafe.compareAndSwapObject(this, headOffset, null, update); } private final boolean compareAndSetTail(Node expect, Node update) { return unsafe.compareAndSwapObject(this, tailOffset, expect, update); } private static final boolean compareAndSetWaitStatus(Node node, int expect, int update) { return unsafe.compareAndSwapInt(node, waitStatusOffset, expect, update); } private static final boolean compareAndSetNext(Node node, Node expect, Node update) { return unsafe.compareAndSwapObject(node, nextOffset, expect, update); } }