一、概述
Condition就是维护一个条件队列,当AQS的线程在lock()内Condition.await()后,该线程会释放锁,然后进入Condition的条件队列,当别的线程Condition.signal()唤醒他后,他会进入AQS的同步队列等待获得锁
核心方法:await()、signal()、signalAll()
二、源码
1、接口
public interface Condition { //当前线程在接到信号或中断之前一直处于等待状态 void await() throws InterruptedException; //当前线程在接到信号或中断之前一直处于等待状态,如果超时则返回false boolean await(long time, TimeUnit unit) throws InterruptedException; //当前线程在接到信号或中断之前一直处于等待状态,如果超时则返回-1,没超时就返回剩余的等待时间 long awaitNanos(long nanosTimeout) throws InterruptedException; //当前线程在接到信号或中断之前一直处于等待状态,如果超过最后期限则返回false boolean awaitUntil(Date deadline) throws InterruptedException; //无法中断的等待 void awaitUninterruptibly(); //唤醒一个等待线程,线程必须先获得锁 void signal(); //唤醒所有等待线程,能返回的线程必须获取相关的锁 void signalAll(); }
2、属性
//队列的首节点 private transient Node firstWaiter; //队列的尾节点 private transient Node lastWaiter; //代表线程是在 signal 后被中断的 private static final int REINTERRUPT = 1; //代表线程是在 signal 前被中断的 private static final int THROW_IE = -1;
3、私有方法
//添加lastWaiter private Node addConditionWaiter() { Node t = lastWaiter; //如果lastWaiter是取消状态 if (t != null && t.waitStatus != Node.CONDITION) { //向前清理取消状态的waiter unlinkCancelledWaiters(); t = lastWaiter; } //创建新节点,作为lastWaiter Node node = new Node(Thread.currentThread(), Node.CONDITION); if (t == null) firstWaiter = node; else t.nextWaiter = node; lastWaiter = node; return node; } //向前清理取消状态的waiter 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; } } //删除或者转移节点到同步队列中,直到获取的节点是不可取消节点,或者null 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); } //确认线程的中断情况 private int checkInterruptWhileWaiting(Node node) { return Thread.interrupted() ? (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) : 0; } //根据interruptMode来确定是应该抛出InterruptedException还是继续中断 private void reportInterruptAfterWait(int interruptMode) throws InterruptedException { if (interruptMode == THROW_IE) throw new InterruptedException(); else if (interruptMode == REINTERRUPT) selfInterrupt(); }
4、公共方法
public ConditionObject() { } public final void signal() { //只有用到condition才需要实现,判断当前线程是否获得独占锁 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); } public final void awaitUninterruptibly() { Node node = addConditionWaiter(); int savedState = fullyRelease(node); boolean interrupted = false; while (!isOnSyncQueue(node)) { LockSupport.park(this); if (Thread.interrupted()) interrupted = true; } if (acquireQueued(node, savedState) || interrupted) selfInterrupt(); } public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); //放弃所有持有的锁 int savedState = fullyRelease(node); int interruptMode = 0; //阻塞判断,当前node是不是在同步队列时,不在同步队列那么就park当前线程 while (!isOnSyncQueue(node)) { LockSupport.park(this); //如果被中断了,则检测中断 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } //这是此节点已经在同步队列中了 //在队列中获取锁,并判断当前的interruptMode不为-1,即不是抛出异常 if (acquireQueued(node, savedState) && interruptMode != THROW_IE) //把中断类型设置为,重新中断,意味在线程获得锁的时候,重新中断线程 interruptMode = REINTERRUPT; if (node.nextWaiter != null) // clean up if cancelled unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); } public final long awaitNanos(long nanosTimeout) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); final long deadline = System.nanoTime() + nanosTimeout; int interruptMode = 0; while (!isOnSyncQueue(node)) { if (nanosTimeout <= 0L) { transferAfterCancelledWait(node); break; } if (nanosTimeout >= spinForTimeoutThreshold) LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; nanosTimeout = deadline - System.nanoTime(); } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); return deadline - System.nanoTime(); } public final boolean awaitUntil(Date deadline) throws InterruptedException { long abstime = deadline.getTime(); if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); boolean timedout = false; int interruptMode = 0; while (!isOnSyncQueue(node)) { if (System.currentTimeMillis() > abstime) { timedout = transferAfterCancelledWait(node); break; } LockSupport.parkUntil(this, abstime); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); return !timedout; } public final boolean await(long time, TimeUnit unit) throws InterruptedException { long nanosTimeout = unit.toNanos(time); if (Thread.interrupted()) throw new InterruptedException(); Node node = addConditionWaiter(); int savedState = fullyRelease(node); final long deadline = System.nanoTime() + nanosTimeout; boolean timedout = false; int interruptMode = 0; while (!isOnSyncQueue(node)) { if (nanosTimeout <= 0L) { timedout = transferAfterCancelledWait(node); break; } if (nanosTimeout >= spinForTimeoutThreshold) LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; nanosTimeout = deadline - System.nanoTime(); } if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); return !timedout; }
5、辅助方法
final boolean isOwnedBy(AbstractQueuedSynchronizer sync) { return sync == AbstractQueuedSynchronizer.this; } protected final boolean hasWaiters() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); for (Node w = firstWaiter; w != null; w = w.nextWaiter) { if (w.waitStatus == Node.CONDITION) return true; } return false; } protected final int getWaitQueueLength() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); int n = 0; for (Node w = firstWaiter; w != null; w = w.nextWaiter) { if (w.waitStatus == Node.CONDITION) ++n; } return n; } protected final Collection<Thread> getWaitingThreads() { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); ArrayList<Thread> list = new ArrayList<Thread>(); for (Node w = firstWaiter; w != null; w = w.nextWaiter) { if (w.waitStatus == Node.CONDITION) { Thread t = w.thread; if (t != null) list.add(t); } } return list; }