其他分享
首页 > 其他分享> > AQS.acquireQueued

AQS.acquireQueued

作者:互联网

通过addWaiter方法把线程添加到链表后,会接着把Node作为参数传递给acquireQueued方法,去竞争锁

1. 获取当前节点的prev节点

2. 如果prev节点为head节点,那么它就有资格去争抢锁,调用tryAcquire抢占锁 

3. 抢占锁成功以后,把获得锁的节点设置为head,并且移除原来的初始化head节点

4. 如果获得锁失败,则根据waitStatus决定是否需要挂起线程

5. 最后,通过cancelAcquire取消获得锁的操作

final boolean acquireQueued(final Node node, int arg) { 
	boolean failed = true; 
	try { 
		boolean interrupted = false; 
		for (;;) { 
			final Node p = node.predecessor();//获
			取当前节点的prev节点 
			if (p == head && tryAcquire(arg)) {//如
				果是head节点,说明有资格去争抢锁 
				setHead(node); 
				//获取锁成功,也就是
				ThreadA已经释放了锁,然后设置head为ThreadB获得执行权
				限 
				p.next = null; //把原head节点从链表中
				移除 
				failed = false; 
				return interrupted; 
			} 

			//ThreadA可能还没释放锁,使得ThreadB在执
			行tryAcquire时会返回false 
			if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) 
			interrupted = true; //并且返回当前线程
			在等待过程中有没有中断过。 
		} 
	} finally { 
		if (failed) 
		cancelAcquire(node); 
	} 
}

 

 

标签:node,head,false,AQS,tryAcquire,acquireQueued,boolean,节点
来源: https://blog.csdn.net/Leon_Jinhai_Sun/article/details/111768131