admin管理员组

文章数量:1599899

调用Condition的await()方法(或者以await开头的方法),会使当前线程进入等待队列并释放锁,同时线程状态变为等待状态。当从await()方法返回时,当前线程一定获取了Condition相关联的锁

public final void await() throws InterruptedException { 
	if (Thread.interrupted()) //表示await允许被	中断 throw new InterruptedException(); 
	Node node = addConditionWaiter(); //创建一个	新的节点,节点状态为condition,采用的数据结构仍然是链表 
	int savedState = fullyRelease(node); //释放当前的锁,得到锁的状态,并唤醒AQS队列中的一个线程 
	int interruptMode = 0; 
	//如果当前节点没有在同步队列上,即还没有被signal,则将当前线程阻塞 
	while (!isOnSyncQueue(node)) {//判断这个节点是否在AQS队列上,第一次判断的是false,因为前面已经释放锁了 
	LockSupport.park(this); 
	//通过park挂起当前线程 
	 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) 
	break; 
	} 
	// 当这个线程醒来,会尝试拿锁, 当 acquireQueued 返回 false 就是拿到锁了. 

	 // interruptMode != THROW_IE -> 表示这个线程没有成功将 node 入队,但 signal 执行了 enq 方法让其入队了. 

	// 将这个变量设置成 REINTERRUPT. 
	if (acquireQueued(node, savedState) && interruptMode != THROW_IE) 
	interruptMode = REINTERRUPT; 
	// 如果 node 的下一个等待者不是 null, 则进行清理,清理 Condition 队列上的节点. 
	// 如果是 null ,就没有什么好清理的了. 
	if (node.nextWaiter != null) // clean up if cancelled 
	unlinkCancelledWaiters(); 
	// 如果线程被中断了,需要抛出异常.或者什么都不做 
	if (interruptMode != 0) 
	reportInterruptAfterWait(interruptMode); 
}

 

本文标签: conditionawait