先看下源码的结构:
可见是sync的newCondition。
abstract static class Sync extends AbstractQueuedSynchronizer {}
可见:
final ConditionObject newCondition() {
return new ConditionObject();
}
再往下:
public class ConditionObject implements Condition, java.io.Serializable {}
--------------------------------------------------------------------------------------------------------------------------
我们用的主要就是两个方法:
await(),single()。
看下await方法:
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();// 放在等待队列中 放在等待队列1
int savedState = fullyRelease(node);// 释放所有的 释放所有2
int interruptMode = 0;
while (!isOnSyncQueue(node)) {//判断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);
}
放在等待队列1:
知识点:没有拿到锁就等待放在同步队列中 和 等待队列await之后。
wait放在同步队列 await放在等待队列。
private Node addConditionWaiter() {
Node t = lastWaiter; // 还是复用的reententLock作为的数据结构
// If lastWaiter is cancelled, clean out.
if (t != null && t.waitStatus != Node.CONDITION) {
unlinkCancelledWaiters();
t = lastWaiter;// 此时t指向最后一个节点,也就是处于等待状态的节点
}
Node node = new Node(Thread.currentThread(), Node.CONDITION);
if (t == null)
firstWaiter = node;
else
t.nextWaiter = node;
lastWaiter = node;
return node;
}
等待队列的同步队列是非常类似的。这个是过滤的。创建的节点放在最后,指针也指向找个节点。
这个是单向链表。
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;
else
trail.nextWaiter = next;
if (next == null)
lastWaiter = trail;
}
else
trail = t;
t = next;
}
}
释放所有2,使用waot的话要把拿到的所有的锁都释放掉
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;
}
}
同步队列是什么?
调用了lock方法,会进入同步的队列,会去抢占cpu的资源的。
--------------------
public final void signal() {
if (!isHeldExclusively())// 看看是不是独占锁
throw new IllegalMonitorStateException();
Node first = firstWaiter;// 指向firetWaiter
if (first != null)
doSignal(first);
}
private void doSignal(Node first) {
do {
if ( (firstWaiter = first.nextWaiter) == null)
lastWaiter = 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))
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))
LockSupport.unpark(node.thread);
return true;
}
-------------
await就是在等待队列的尾部插入一个节点。
signal就是在头部移除一个节点。放在同步队列里面,竞争资源。
一个线程创建多个condition,有多个等待队列。