【2】但 , condition的使用必须依赖于lock对象 , 通过lock对象的newCondition()方法初始化一个condition对象 。
ConditionObject类详解【Condition接口的实现类】1.属性值解析
//由头尾两个节点指针形成的链表来达到队列的效果private transient Node firstWaiter;private transient Node lastWaiter;2.方法解析
【1】核心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;}//此时已经被唤醒 , 那么尝试获取锁if (acquireQueued(node, savedState) && interruptMode != THROW_IE)interruptMode = REINTERRUPT;//如果节点中断取消 , 那么清除节点if (node.nextWaiter != null) // clean up if cancelledunlinkCancelledWaiters();if (interruptMode != 0)reportInterruptAfterWait(interruptMode);}//addConditionWaiter将一个节点添加到condition队列中 。在入队时 , 判断当前尾节点是不是CONDITION 。如果不是则判断当前尾节点已经被取消 , 将当前节点出队 。那么也就是说在队列中的节点状态 , 要么是CONDITION,要么是CANCELLEDprivate 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;elset.nextWaiter = node;lastWaiter = node;return node;}//方法的作用是移除取消的节点 。方法本身只有在持有锁的时候会被调用 。方法会遍历当前condition队列 , 将所有非Condition状态的节点移除 。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;elsetrail.nextWaiter = next;if (next == null)lastWaiter = trail;}elsetrail = t;t = next;}}【2】核心signal方法与signalAll方法
public final void signal() {if (!isHeldExclusively())throw new IllegalMonitorStateException();Node first = firstWaiter;if (first != null)doSignal(first);}public final void signalAll() {if (!isHeldExclusively())throw new IllegalMonitorStateException();Node first = firstWaiter;if (first != null)doSignalAll(first);}private void doSignal(Node first) {do {if ( (firstWaiter = first.nextWaiter) == null)lastWaiter = null;first.nextWaiter = null;} while (!transferForSignal(first) &&(first = firstWaiter) != null);}private void doSignalAll(Node first) {lastWaiter = firstWaiter = null;do {Node next = first.nextWaiter;first.nextWaiter = null;transferForSignal(first);first = next;} while (first != null);}final boolean transferForSignal(Node node) {//如果不能更改waitStatus , 则表示该节点已被取消if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))return false;Node p = enq(node);int ws = p.waitStatus;if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))LockSupport.unpark(node.thread);return true;}
- 主要用于维护获取锁失败时入队的线程
经验总结扩展阅读
- 面对爱情总是浅尝即止,不会深入的星座
- 对循环神经网络参数的理解|LSTM RNN Input_size Batch Sequence
- 怎样联系上下文理解词语的意思
- 深入底层C源码 Redis核心设计原理
- 如何准确理解税收法定原则
- 你如何理解给予是快乐的
- 俊义的寓意
- 2023年正月初一春节出生的女宝宝命理解析 2023年出生是什么命
- 理解生命在于运动这句名言
- 如何理解社会保障的含义