前置知识
volatile:Java的语义 原子性,有序性,可见性
而 Java 是由C语言实现的,所以 C 语言也有其对 volatile 实现。
编译器也会对代码进行优化,而有时候并不是 CPU 导致的问题,因为CPU只是引入了 MQ,MQ的特征是最终一致性,并不会导致不可见,只是晚一点,而 C 语言的 volatile 告诉编译器这段代码不需要优化而已,编译会认为当前字段不需要重新从缓存中获取,这就会导致不可见,这样就获取不到最新值。
抽象类 :AbstractOwnableSynchronizer
exclusiveOwnerThread 当前执行的线程
抽象类 :AbstractQueuedSynchronizer
Node
static final class Node { static final Node SHARED = new Node(); static final Node EXCLUSIVE = null; // 取消状态 static final int CANCELLED = 1; // 在等待队列中,被唤醒状态 static final int SIGNAL = -1; // 该节点当前处于条件队列中。(条件遍历) static final int CONDITION = -2; // 共享锁,是否被别人唤醒 static final int PROPAGATE = -3; /** * Status field, taking on only the values: * SIGNAL: The successor of this node is (or will soon be) * blocked (via park), so the current node must * unpark its successor when it releases or * cancels. To avoid races, acquire methods must * first indicate they need a signal, * then retry the atomic acquire, and then, * on failure, block. * CANCELLED: This node is cancelled due to timeout or interrupt. * Nodes never leave this state. In particular, * a thread with cancelled node never again blocks. * CONDITION: This node is currently on a condition queue. * It will not be used as a sync queue node * until transferred, at which time the status * will be set to 0. (Use of this value here has * nothing to do with the other uses of the * field, but simplifies mechanics.) * PROPAGATE: A releaseShared should be propagated to other * nodes. This is set (for head node only) in * doReleaseShared to ensure propagation * continues, even if other operations have * since intervened. * 0: None of the above * * The values are arranged numerically to simplify use. * Non-negative values mean that a node doesn't need to * signal. So, most code doesn't need to check for particular * values, just for sign. * * The field is initialized to 0 for normal sync nodes, and * CONDITION for condition nodes. It is modified using CAS * (or when possible, unconditional volatile writes). */ volatile int waitStatus; volatile Node prev; /** * Link to the successor node that the current node/thread * unparks upon release. Assigned during enqueuing, adjusted * when bypassing cancelled predecessors, and nulled out (for * sake of GC) when dequeued. The enq operation does not * assign next field of a predecessor until after attachment, * so seeing a null next field does not necessarily mean that * node is at end of queue. However, if a next field appears * to be null, we can scan prev's from the tail to * double-check. The next field of cancelled nodes is set to * point to the node itself instead of null, to make life * easier for isOnSyncQueue. */ volatile Node next; /** * The thread that enqueued this node. Initialized on * construction and nulled out after use. */ volatile Thread thread; /** * Link to next node waiting on condition, or the special * value SHARED. Because condition queues are accessed only * when holding in exclusive mode, we just need a simple * linked queue to hold nodes while they are waiting on * conditions. They are then transferred to the queue to * re-acquire. And because conditions can only be exclusive, * we save a field by using special value to indicate shared * mode. */ Node nextWaiter; }
volatile 支持原子性,有序性,可见性
队列:使用双向链表记录队列
volatile head 头结点
volatile tail 尾结点
volatile state 状态
AQS 提供一个状态让子类自己去实现:如果利用这个状态去自己实现获取资源和释放资源
tryRelease 尝试释放资源
acquire 获取资源
// 尝试获取锁,如果获取锁失败,去添加到队列中区 public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
tryAcquire 尝试获取资源
// 在抽象模板类中,定义方法,具体如何实现,由子类自行决定 protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); }
ReentrantLock 互斥锁实现
protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } public void lock() { sync.acquire(1); }
/** * Base of synchronization control for this lock. Subclassed * into fair and nonfair versions below. Uses AQS state to * represent the number of holds on the lock. */ abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -5179523762034025860L; /** * Performs non-fair tryLock. tryAcquire is implemented in * subclasses, but both need nonfair try for trylock method. */ @ReservedStackAccess final boolean nonfairTryAcquire(int acquires) { // 获取当前线程 当前 acquires = 1 final Thread current = Thread.currentThread(); // 获取状态 int c = getState(); // 如果当前状态是 初始化 抢锁,设置为 1 if (c == 0) { if (compareAndSetState(0, acquires)) { // 设置当前线程独占 setExclusiveOwnerThread(current); return true; } } // 如果当前线程是已经独占,锁重入,累加1 else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } @ReservedStackAccess protected final boolean tryRelease(int releases) { // 释放可重入 int c = getState() - releases; // 如果持有线程 不是当前 线程 则抛出异常 if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; // 如果可重入为 0 则将持有的线程置空,标记为空闲 if (c == 0) { free = true; setExclusiveOwnerThread(null); } // 设置状态 setState(c); return free; } protected final boolean isHeldExclusively() { // While we must in general read state before owner, // we don't need to do so to check if current thread is owner return getExclusiveOwnerThread() == Thread.currentThread(); } final ConditionObject newCondition() { return new ConditionObject(); } // Methods relayed from outer class final Thread getOwner() { return getState() == 0 ? null : getExclusiveOwnerThread(); } final int getHoldCount() { return isHeldExclusively() ? getState() : 0; } final boolean isLocked() { return getState() != 0; } /** * Reconstitutes the instance from a stream (that is, deserializes it). */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); setState(0); // reset to unlocked state } }
FairSync -> Sync -> AbstractQueuedSynchronizer 公平锁
/** * Sync object for fair locks */ static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; /** * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ // 公平锁,先看队列,有队列去排队。 @ReservedStackAccess protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); // 如果当前锁无人使用 if (c == 0) { // 看一下队列中有没有任务,如果没有任务,尝试获取锁,设置当前线程为独占 if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } // 如果当前线程已经独占,可重入 else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } }
NonfairSync -> Sync -> AbstractQueuedSynchronizer 非公平锁
/** * Sync object for non-fair locks */ static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; // 非公平锁直接上来抢独占,如果抢不到进队列 protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }
ReentrantReadWriteLock 读写锁,读共享,读写,写写互斥
//写锁 public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } //读锁 public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
/** * Synchronization implementation for ReentrantReadWriteLock. * Subclassed into fair and nonfair versions. */ // 自己实现公平锁与非公平锁,抽象类定义模板 abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 6317671515068378041L; /* * Read vs write count extraction constants and functions. * Lock state is logically divided into two unsigned shorts: * The lower one representing the exclusive (writer) lock hold count, * and the upper the shared (reader) hold count. */ // 使用 state 变量,高16位 与 低 16 位区分是 读锁还是写锁,便于CAS static final int SHARED_SHIFT = 16; static final int SHARED_UNIT = (1 << SHARED_SHIFT); static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; /** Returns the number of shared holds represented in count */ static int sharedCount(int c) { return c >>> SHARED_SHIFT; } /** Returns the number of exclusive holds represented in count */ static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; } /** * A counter for per-thread read hold counts. * Maintained as a ThreadLocal; cached in cachedHoldCounter */ static final class HoldCounter { int count = 0; // Use id, not reference, to avoid garbage retention final long tid = getThreadId(Thread.currentThread()); } /** * ThreadLocal subclass. Easiest to explicitly define for sake * of deserialization mechanics. */ static final class ThreadLocalHoldCounter extends ThreadLocal<HoldCounter> { public HoldCounter initialValue() { return new HoldCounter(); } } /** * The number of reentrant read locks held by current thread. * Initialized only in constructor and readObject. * Removed whenever a thread's read hold count drops to 0. */ private transient ThreadLocalHoldCounter readHolds; /** * The hold count of the last thread to successfully acquire * readLock. This saves ThreadLocal lookup in the common case * where the next thread to release is the last one to * acquire. This is non-volatile since it is just used * as a heuristic, and would be great for threads to cache. * * <p>Can outlive the Thread for which it is caching the read * hold count, but avoids garbage retention by not retaining a * reference to the Thread. * * <p>Accessed via a benign data race; relies on the memory * model's final field and out-of-thin-air guarantees. */ private transient HoldCounter cachedHoldCounter; /** * firstReader is the first thread to have acquired the read lock. * firstReaderHoldCount is firstReader's hold count. * * <p>More precisely, firstReader is the unique thread that last * changed the shared count from 0 to 1, and has not released the * read lock since then; null if there is no such thread. * * <p>Cannot cause garbage retention unless the thread terminated * without relinquishing its read locks, since tryReleaseShared * sets it to null. * * <p>Accessed via a benign data race; relies on the memory * model's out-of-thin-air guarantees for references. * * <p>This allows tracking of read holds for uncontended read * locks to be very cheap. */ private transient Thread firstReader = null; private transient int firstReaderHoldCount; Sync() { readHolds = new ThreadLocalHoldCounter(); setState(getState()); // ensures visibility of readHolds } /* * Acquires and releases use the same code for fair and * nonfair locks, but differ in whether/how they allow barging * when queues are non-empty. */ /** * Returns true if the current thread, when trying to acquire * the read lock, and otherwise eligible to do so, should block * because of policy for overtaking other waiting threads. */ abstract boolean readerShouldBlock(); /** * Returns true if the current thread, when trying to acquire * the write lock, and otherwise eligible to do so, should block * because of policy for overtaking other waiting threads. */ abstract boolean writerShouldBlock(); /* * Note that tryRelease and tryAcquire can be called by * Conditions. So it is possible that their arguments contain * both read and write holds that are all released during a * condition wait and re-established in tryAcquire. */ // 尝试释放锁 protected final boolean tryRelease(int releases) { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); // 可重入锁 int nextc = getState() - releases; // 互斥锁是否有人在使用 // (1 << SHARED_SHIFT) - 1 => 1 << 16 位 - 1 // 0x0000 0001 => 0x0001 0000 - 1 = 0x0000 ffff // 0000 0001 => 1 // 0001 0000 0000 0000 0000 16 => (1 << 16) 0000 = f // 1111 1111 1111 1111 => (1 << 16) - 1 // 0xffff // 说明互斥锁最大可支持 65535 // 如果没有互斥锁,也即写线程的数量 boolean free = exclusiveCount(nextc) == 0; // 将当前前持有线程置位空 if (free) setExclusiveOwnerThread(null); // 将状态更新 setState(nextc); return free; } // 获取锁,当前方法为互斥锁 protected final boolean tryAcquire(int acquires) { /* * Walkthrough: * 1. If read count nonzero or write count nonzero * and owner is a different thread, fail. * 2. If count would saturate, fail. (This can only * happen if count is already nonzero.) * 3. Otherwise, this thread is eligible for lock if * it is either a reentrant acquire or * queue policy allows it. If so, update state * and set owner. */ Thread current = Thread.currentThread(); int c = getState(); // 获取写线程的数量 int w = exclusiveCount(c); // 如果不等于 0 ,说明有读线程或者是写线程 if (c != 0) { // (Note: if c != 0 and w == 0 then shared count != 0) // 如果没有写线程,但是当前线程不是和管程中持有的线程不一致 // 说明这里是锁标记是读锁,返回 false,没有写锁不需要抢锁。 // 读读共享,直接读,写锁获取读锁,也是可以的,锁降级。 // 如果有写锁,并且当前线程不是管程中占有的线程,放弃抢锁,应当去排队,读写互斥,写写互斥 if (w == 0 || current != getExclusiveOwnerThread()) return false; // 如果当前写线程数量超过最大值 // 则抛出异常 MAX_COUNT (1 << 16) - 1 => 65535 if (w + exclusiveCount(acquires) > MAX_COUNT) throw new Error("Maximum lock count exceeded"); // Reentrant acquire // 累加 setState(c + acquires); return true; } // 判断写锁是否需要去阻塞,公平锁和非公平锁的实现 // 如果需要去阻塞返回false,如果不需要进队列,去累加, // 抢锁成功返回 true 设置管程中的线程为当前线程 if (writerShouldBlock() || !compareAndSetState(c, c + acquires)) return false; setExclusiveOwnerThread(current); return true; } // 尝试释放共享锁 protected final boolean tryReleaseShared(int unused) { Thread current = Thread.currentThread(); // firstReader 为一个优化,为了记录当前第一个读线程 // 如果当前为第一个只需要判断即可,快 // 因为线程是需要自己获取过多少次锁 // 所以每个线程的状态都需要自己单独保存,state 变量就无法实现了 if (firstReader == current) { // assert firstReaderHoldCount > 0; if (firstReaderHoldCount == 1) firstReader = null; else firstReaderHoldCount--; } else { // 从缓存中获取 HoldCounter rh = cachedHoldCounter; // 如果缓存为空,从缓存列表中获取 // 如果缓存不为空,则判断当前线程的Id号是否相同,如果线程号不相同,则还是从缓存列表中获取 if (rh == null || rh.tid != getThreadId(current)) rh = readHolds.get(); // 获取当前线程,锁的数量 int count = rh.count; // 如果是 1 删除,为0 抛出异常 if (count <= 1) { readHolds.remove(); if (count <= 0) throw unmatchedUnlockException(); } // 减少 --rh.count; } for (;;) { int c = getState(); // 共享锁 - 1 // 因为高 16 为读锁 // SHARED_UNIT => (1 << SHARED_SHIFT) => 1 0000 0000 // state - SHARED_UNIT 就是将高16 - 1 int nextc = c - SHARED_UNIT; // CAS 释放 是否读锁为 0 if (compareAndSetState(c, nextc)) // Releasing the read lock has no effect on readers, // but it may allow waiting writers to proceed if // both read and write locks are now free. return nextc == 0; } } private IllegalMonitorStateException unmatchedUnlockException() { return new IllegalMonitorStateException( "attempt to unlock read lock, not locked by current thread"); } // 尝试获取共享锁 protected final int tryAcquireShared(int unused) { /* * Walkthrough: * 1. If write lock held by another thread, fail. * 2. Otherwise, this thread is eligible for * lock wrt state, so ask if it should block * because of queue policy. If not, try * to grant by CASing state and updating count. * Note that step does not check for reentrant * acquires, which is postponed to full version * to avoid having to check hold count in * the more typical non-reentrant case. * 3. If step 2 fails either because thread * apparently not eligible or CAS fails or count * saturated, chain to version with full retry loop. */ Thread current = Thread.currentThread(); int c = getState(); // 如果有写锁,并且当前线程和管程中拥有的线程不一致,返回失败 if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return -1; // 获取读锁 int r = sharedCount(c); // 读锁是否需要排队到写锁,读锁是否超出限制,读锁是否可以取锁成功 if (!readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) { // 当前线程是第一个读 // 缓存一个即可 if (r == 0) { firstReader = current; firstReaderHoldCount = 1; // 如果读列表只有一个,并且当前线程是一个读,累加 } else if (firstReader == current) { firstReaderHoldCount++; } else { // 如果列表中有多个,则累加 // 并且缓存设置为当前线程 HoldCounter rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) cachedHoldCounter = rh = readHolds.get(); else if (rh.count == 0) readHolds.set(rh); rh.count++; } return 1; } return fullTryAcquireShared(current); } /** * Full version of acquire for reads, that handles CAS misses * and reentrant reads not dealt with in tryAcquireShared. */ // 尝试获取所有的共享锁 final int fullTryAcquireShared(Thread current) { /* * This code is in part redundant with that in * tryAcquireShared but is simpler overall by not * complicating tryAcquireShared with interactions between * retries and lazily reading hold counts. */ HoldCounter rh = null; for (;;) { int c = getState(); // 如果有互斥锁 if (exclusiveCount(c) != 0) { // 当前线程不是管程中的线程返回 if (getExclusiveOwnerThread() != current) return -1; // else we hold the exclusive lock; blocking here // would cause deadlock. // 尝试获取读线程,是否会被写线程阻塞,高16位为读锁 } else if (readerShouldBlock()) { // Make sure we're not acquiring read lock reentrantly if (firstReader == current) { // assert firstReaderHoldCount > 0; } else { if (rh == null) { rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) { rh = readHolds.get(); if (rh.count == 0) readHolds.remove(); } } if (rh.count == 0) return -1; } } // 如果读线程超过范围,报错 if (sharedCount(c) == MAX_COUNT) throw new Error("Maximum lock count exceeded"); // 读线程累加,缓存读锁 if (compareAndSetState(c, c + SHARED_UNIT)) { if (sharedCount(c) == 0) { firstReader = current; firstReaderHoldCount = 1; } else if (firstReader == current) { firstReaderHoldCount++; } else { if (rh == null) rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) rh = readHolds.get(); else if (rh.count == 0) readHolds.set(rh); rh.count++; cachedHoldCounter = rh; // cache for release } return 1; } } } /** * Performs tryLock for write, enabling barging in both modes. * This is identical in effect to tryAcquire except for lack * of calls to writerShouldBlock. */ // 尝试获取写锁 final boolean tryWriteLock() { Thread current = Thread.currentThread(); // 获取锁状态 int c = getState(); if (c != 0) { // 获取写锁状态 int w = exclusiveCount(c); // 如果没有写锁,说明有读锁 // 如果有写锁,看一下管程中的线程是不是自己,如果不是返回 false if (w == 0 || current != getExclusiveOwnerThread()) return false; // 判断写锁是否到达最大值 if (w == MAX_COUNT) throw new Error("Maximum lock count exceeded"); } // 获取写锁,成功后将管程独占,返回成功 if (!compareAndSetState(c, c + 1)) return false; setExclusiveOwnerThread(current); return true; } /** * Performs tryLock for read, enabling barging in both modes. * This is identical in effect to tryAcquireShared except for * lack of calls to readerShouldBlock. */ // 尝试获取读锁 final boolean tryReadLock() { Thread current = Thread.currentThread(); // 因为读锁是共享锁,队列中都是读的话,需要循环唤醒,直到遇到写线程去排队。 // 避免写线程饥饿。 for (;;) { // 获取锁状态 int c = getState(); // 获取写锁,如果有写锁,直接返回 if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return false; // 获取读锁 int r = sharedCount(c); // 读锁到了最大值,则报错 if (r == MAX_COUNT) throw new Error("Maximum lock count exceeded"); // 获取读锁。 if (compareAndSetState(c, c + SHARED_UNIT)) { if (r == 0) { firstReader = current; firstReaderHoldCount = 1; } else if (firstReader == current) { firstReaderHoldCount++; } else { HoldCounter rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) cachedHoldCounter = rh = readHolds.get(); else if (rh.count == 0) readHolds.set(rh); rh.count++; } return true; } } } protected final boolean isHeldExclusively() { // While we must in general read state before owner, // we don't need to do so to check if current thread is owner return getExclusiveOwnerThread() == Thread.currentThread(); } // Methods relayed to outer class final ConditionObject newCondition() { return new ConditionObject(); } final Thread getOwner() { // Must read state before owner to ensure memory consistency return ((exclusiveCount(getState()) == 0) ? null : getExclusiveOwnerThread()); } final int getReadLockCount() { return sharedCount(getState()); } final boolean isWriteLocked() { return exclusiveCount(getState()) != 0; } final int getWriteHoldCount() { return isHeldExclusively() ? exclusiveCount(getState()) : 0; } final int getReadHoldCount() { if (getReadLockCount() == 0) return 0; Thread current = Thread.currentThread(); if (firstReader == current) return firstReaderHoldCount; HoldCounter rh = cachedHoldCounter; if (rh != null && rh.tid == getThreadId(current)) return rh.count; int count = readHolds.get().count; if (count == 0) readHolds.remove(); return count; } /** * Reconstitutes the instance from a stream (that is, deserializes it). */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); readHolds = new ThreadLocalHoldCounter(); setState(0); // reset to unlocked state } final int getCount() { return getState(); } }
FairSync -> Sync -> AbstractQueuedSynchronizer 公平锁
/** * Fair version of Sync */ static final class FairSync extends Sync { private static final long serialVersionUID = -2274990926593161451L; // 写 final boolean writerShouldBlock() { return hasQueuedPredecessors(); } // 读 final boolean readerShouldBlock() { return hasQueuedPredecessors(); } }
NonfairSync -> Sync -> AbstractQueuedSynchronizer 非公平锁
/** * Nonfair version of Sync */ static final class NonfairSync extends Sync { private static final long serialVersionUID = -8159625535654395037L; // 如果获取写,直接排队 final boolean writerShouldBlock() { return false; // writers can always barge } // 读锁,去队列中看一下,是否能可以将读全唤醒,直到遇到写锁 final boolean readerShouldBlock() { /* As a heuristic to avoid indefinite writer starvation, * block if the thread that momentarily appears to be head * of queue, if one exists, is a waiting writer. This is * only a probabilistic effect since a new reader will not * block if there is a waiting writer behind other enabled * readers that have not yet drained from the queue. */ return apparentlyFirstQueuedIsExclusive(); } }
tryRelease 尝试释放资源
@ReservedStackAccess protected final boolean tryRelease(int releases) { int c = getState() - releases; // 当释放时,当前线程并不是独占资源的线程,则抛出异常 if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; // 如果可重入锁,为0了,将当前锁置位。 if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; }
release 释放资源
/** * Releases in exclusive mode. Implemented by unblocking one or * more threads if {@link #tryRelease} returns true. * This method can be used to implement method {@link Lock#unlock}. * * @param arg the release argument. This value is conveyed to * {@link #tryRelease} but is otherwise uninterpreted and * can represent anything you like. * @return the value returned from {@link #tryRelease} */ public final boolean release(int arg) { // 尝试释放锁 if (tryRelease(arg)) { Node h = head; // 如果头结点不为空,头结点的不是初始值 if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; } /** * Wakes up node's successor, if one exists. * * @param node the node */ private void unparkSuccessor(Node node) { /* * If status is negative (i.e., possibly needing signal) try * to clear in anticipation of signalling. It is OK if this * fails or if status is changed by waiting thread. */ // 如果当前状态是不是取消状态 int ws = node.waitStatus; if (ws < 0) compareAndSetWaitStatus(node, ws, 0); /* * Thread to unpark is held in successor, which is normally * just the next node. But if cancelled or apparently null, * traverse backwards from tail to find the actual * non-cancelled successor. */ // 当前节点的下一个节点 Node s = node.next; // 下一个节点为空,下一个节点的状态是取消状态 if (s == null || s.waitStatus > 0) { s = null; // 从尾部开始查询,找到一个正常状态的节点,让尾结点跳过前面的节点,且不是头结点 // t 表示前一个节点,t 不为空,t 不是当前节点 for (Node t = tail; t != null && t != node; t = t.prev) if (t.waitStatus <= 0) s = t; } // 如果下一个节点不为空,则将当前节点的线程唤醒 if (s != null) LockSupport.unpark(s.thread); }
acquireQueued 获取队列
/** * Acquires in exclusive uninterruptible mode for thread already in * queue. Used by condition wait methods as well as acquire. * * @param node the node * @param arg the acquire argument * @return {@code true} if interrupted while waiting */ final boolean acquireQueued(final Node node, int arg) { try { boolean interrupted = false; for (;;) { // 获取当前节点的前驱节点 final Node p = node.predecessor(); // 如果前驱节点是 头结点,尝试获取锁 // 获取 if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC return interrupted; } // 如果没有获取到锁,将自己改变为可唤醒状态,阻塞并检查中断 if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } catch (Throwable t) { cancelAcquire(node); throw t; } } /** * Checks and updates status for a node that failed to acquire. * Returns true if thread should block. This is the main signal * control in all acquire loops. Requires that pred == node.prev. * * @param pred node's predecessor holding status * @param node the node * @return {@code true} if thread should block */ private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { int ws = pred.waitStatus; // 如果当前线程处于唤醒状态,直接返回 true if (ws == Node.SIGNAL) /* * This node has already set status asking a release * to signal it, so it can safely park. */ return true; // 只有取消状态是正数,所以将自己连接到不是取消状态的节点 if (ws > 0) { /* * Predecessor was cancelled. Skip over predecessors and * indicate retry. */ // 循环处理,前驱节点,不是取消状态 do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0); pred.next = node; } else { /* * waitStatus must be 0 or PROPAGATE. Indicate that we * need a signal, but don't park yet. Caller will need to * retry to make sure it cannot acquire before parking. */ // 将当前状态设置 为唤醒状态 pred.compareAndSetWaitStatus(ws, Node.SIGNAL); } return false; }
selfInterrupt 中断
/** * Convenience method to interrupt current thread. 自我中断 */ static void selfInterrupt() { Thread.currentThread().interrupt(); }
cancelAcquire 任务取消
/** * Cancels an ongoing attempt to acquire. * * @param node the node */ private void cancelAcquire(Node node) { // Ignore if node doesn't exist if (node == null) return; // 将当前线程置空 node.thread = null; // Skip cancelled predecessors // 当前节点的前置节点,找到前面节点是不是取消状态,重新连接 Node pred = node.prev; while (pred.waitStatus > 0) node.prev = pred = pred.prev; // predNext is the apparent node to unsplice. CASes below will // fail if not, in which case, we lost race vs another cancel // or signal, so no further action is necessary. Node predNext = pred.next; // Can use unconditional write instead of CAS here. // After this atomic step, other Nodes can skip past us. // Before, we are free of interference from other threads. // 将当前节点设置为取消状态 node.waitStatus = Node.CANCELLED; // If we are the tail, remove ourselves. // 当前节点是尾结点,将前一个节点与设置为尾结点 if (node == tail && compareAndSetTail(node, pred)) { // 将前一个节点指向引用取消 pred.compareAndSetNext(predNext, null); } else { // If successor needs signal, try to set pred's next-link // so it will get one. Otherwise wake it up to propagate. int ws; // 前一个节点不是头结点 // 获取前一个节点的状态,如果是唤醒状态,或者状态不是取消状态,并且可以将状态更新为唤醒状态 // 前一个节点的线程不为空 if (pred != head && ((ws = pred.waitStatus) == Node.SIGNAL || (ws <= 0 && pred.compareAndSetWaitStatus(ws, Node.SIGNAL))) && pred.thread != null) { Node next = node.next; // 获取当前节点的下一个节点,下一个节点的状态不是取消状态 // 将当前节点的下一个节点,挂到当前节点的上一个节点上,线程协助 if (next != null && next.waitStatus <= 0) pred.compareAndSetNext(predNext, next); } else { unparkSuccessor(node); } node.next = node; // help GC } } /** * Wakes up node's successor, if one exists. * 唤醒节点 * @param node the node */ private void unparkSuccessor(Node node) { /* * If status is negative (i.e., possibly needing signal) try * to clear in anticipation of signalling. It is OK if this * fails or if status is changed by waiting thread. */ // 获取当前节点的状态 int ws = node.waitStatus; // 如果不是取消状态 if (ws < 0) node.compareAndSetWaitStatus(ws, 0); /* * Thread to unpark is held in successor, which is normally * just the next node. But if cancelled or apparently null, * traverse backwards from tail to find the actual * non-cancelled successor. */ // Node s = node.next; if (s == null || s.waitStatus > 0) { s = null; for (Node p = tail; p != node && p != null; p = p.prev) if (p.waitStatus <= 0) s = p; } if (s != null) LockSupport.unpark(s.thread); }
apparentlyFirstQueuedIsExclusive 队列的头节点的下一个节点是否是互斥锁
/** * Returns {@code true} if the apparent first queued thread, if one * exists, is waiting in exclusive mode. If this method returns * {@code true}, and the current thread is attempting to acquire in * shared mode (that is, this method is invoked from {@link * #tryAcquireShared}) then it is guaranteed that the current thread * is not the first queued thread. Used only as a heuristic in * ReentrantReadWriteLock. */ // 当前头结点不为空,并且下一个节点不是空,下一个节点不是共享锁,下一个节点的线程不为空 final boolean apparentlyFirstQueuedIsExclusive() { Node h, s; return (h = head) != null && (s = h.next) != null && !s.isShared() && s.thread != null; }