
前置知识

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;
}
文章详细介绍了Java中的volatile关键字以及AbstractQueuedSynchronizer(AQS)在实现并发锁中的作用。AQS是很多并发工具如ReentrantLock的基础,它提供了基于状态的同步机制。ReentrantLock分为公平锁和非公平锁,内部使用AQS的tryAcquire和tryRelease方法来尝试获取和释放锁,通过state字段管理锁的状态。文章还提到了读写锁的实现,读锁和写锁的获取与释放策略。
836

被折叠的 条评论
为什么被折叠?



