Condition源码解析
Posted lzh66
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Condition源码解析相关的知识,希望对你有一定的参考价值。
可以通过ReentrantLock.newCondition()来获得Condition对象
public Condition newCondition() { return sync.newCondition(); //实际上是调用AQS的方法 }
final ConditionObject newCondition() { return new ConditionObject(); //ConditionObject实现了Condition方法 }
Condition的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 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); //新建一个Node对象,WaitStatus属性设置为CONDITION if (t == null) firstWaiter = node; //设为首节点 else t.nextWaiter = node; //添加到链表尾 lastWaiter = node; return node; }
final int fullyRelease(Node node) { boolean failed = true; try { int savedState = getState(); if (release(savedState)) { //释放锁,并唤醒队列里的第一个线程 failed = false; return savedState; } else { throw new IllegalMonitorStateException(); } } finally { if (failed) node.waitStatus = Node.CANCELLED; } }
singal()方法
public final void signal() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); Node first = firstWaiter; if (first != null) doSignal(first); //doSignal主要就是把等待队列的第一个节点移动同步队列的尾节点中去 }
private void doSignal(Node first) { do { if ( (firstWaiter = first.nextWaiter) == null)//把下一个节点设为首节点,如果首节点的下一个节点为空,说明队列只有一个节点, lastWaiter = null; //把尾节点置为null; first.nextWaiter = null; //把首节点从队列中清除 } while (!transferForSignal(first) && (first = firstWaiter) != null); }
final boolean transferForSignal(Node node) { /* * If cannot change waitStatus, the node has been cancelled. */ if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) //把节点的waitStatuss设为CONDITION return false; /* * Splice onto queue and try to set waitStatus of predecessor to * indicate that thread is (probably) waiting. If cancelled or * attempt to set waitStatus fails, wake up to resync (in which * case the waitStatus can be transiently and harmlessly wrong). */ Node p = enq(node); //把节点添加到同步队列的尾部 int ws = p.waitStatus; if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL)) //通过cas把节点的waitStatus设为SIGNAL LockSupport.unpark(node.thread); return true; }
所以Condition的await方法和singal方法的作用:
await就是把当前获得锁的线程添加到等待队列中,并阻塞队列,同时释放锁并唤醒同步队列中的线程
singal就是把等待队列的头结点添加到同步队列中的尾部,等待唤醒.
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 cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
以上是关于Condition源码解析的主要内容,如果未能解决你的问题,请参考以下文章