4.1 ConditionObject

喜夏-厌秋 提交于 2020-08-12 14:18:57

在这个类里AbstractQueuedSynchronizer

 public class ConditionObject implements Condition, java.io.Serializable {}

属性

就这俩没有了

  /** First node of condition queue. */
        private transient Node firstWaiter;
        /** Last node of condition queue. */
        private transient Node lastWaiter;

newCondition

private final Condition notFull = putLock.newCondition();
  public Condition newCondition() {
        return sync.newCondition();
    }
	  final ConditionObject newCondition() {
            return new ConditionObject();
        }
		//毛也没有啊 
		 public ConditionObject() { }

public boolean offer(E e, long timeout, TimeUnit unit){
   ...
   //在这里有这么一句 当容量到达上限 就调用了await
     while (count.get() == capacity) {
                if (nanos <= 0)
                    return false;
                nanos = notFull.awaitNanos(nanos);
            }
   ....
}
//这个方法里也有
 public void put(E e) {
 
     while (count.get() == capacity) {
                notFull.await();
            }
 }

await

public final void await() throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
				//添加等待节点 那两个属性用上了
            Node node = addConditionWaiter();
			//找到同步队列的线程 唤醒一个
            int savedState = fullyRelease(node);
            int interruptMode = 0;
			
            while (!isOnSyncQueue(node)) {
			   //挂起线程
                LockSupport.park(this);
                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                    break;
            }
			//满足条件了 到这里了 把自己加入等待队列中
			//此处的acquireQueued 和 加锁的那个一样《具体看3.2节》
            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                interruptMode = REINTERRUPT;
            if (node.nextWaiter != null) // clean up if cancelled
                unlinkCancelledWaiters();
            if (interruptMode != 0)
                reportInterruptAfterWait(interruptMode);
        }
private Node addConditionWaiter() {
            Node t = lastWaiter;
            // If lastWaiter is cancelled, clean out.
            if (t != null && t.waitStatus != Node.CONDITION) {
                unlinkCancelledWaiters();
                t = lastWaiter;
            }
            Node node = new Node(Thread.currentThread(), Node.CONDITION);
            if (t == null)
                firstWaiter = node;
            else
                t.nextWaiter = node;
            lastWaiter = node;
            return node;
        }
		
		 final boolean isOnSyncQueue(Node node) {
		  //判断节点的状态,如果状态是CONDITION,说明节点肯定不在同步队列中,
		  同时哪怕同步队列是刚刚初始化的,也会有一个冗余的头节点存在,
		  所以节点的前驱节点如果为null,那么节点也肯定不在同步队列中,返回fasle
        if (node.waitStatus == Node.CONDITION || node.prev == null)
            return false;
			//节点的后继节点不为null,说明节点肯定在队列中,返回true,这里很重要的一点要明白,prev和next都是针对同步队列的节点
        if (node.next != null) // If has successor, it must be on queue
            return true;
        /*
         * node.prev can be non-null, but not yet on queue because
         * the CAS to place it on queue can fail. So we have to
         * traverse from tail to make sure it actually made it.  It
         * will always be near the tail in calls to this method, and
         * unless the CAS failed (which is unlikely), it will be
         * there, so we hardly ever traverse much.
         */
		  //调用findNodeFromTail,具体返回结果看findNodeFromTail()方法返回值,可以把这个方法想象成一个兜底的方法
        return findNodeFromTail(node);
    }
	private boolean findNodeFromTail(Node node) {
    //取得同步队列的队尾元素
    Node t = tail;
    //无限循环,从队尾元素一直往前找,找到相等的节点就说明节点在队列中,node为null了,说明前面已经没有节点可以找了,那就返回false
    for (;;) {
        if (t == node)
            return true;
        if (t == null)
            return false;
        t = t.prev;
    }
}
		
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!