package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;
import java.util.Collection;
//不同线程之间读锁和写锁互斥(有读就不能写,有写不能读),有读可继续读(读锁可以多个),有写不能再写(写锁只能1个)
//同一个线程之间,获取读锁后不能再获取写锁,但如果获取了写锁当前线程可以再获取读锁,但其它线程无法获取读/写锁
public class ReentrantReadWriteLock
implements ReadWriteLock, java.io.Serializable {
private static final long serialVersionUID = -6992448646407690164L;
/** Inner class providing readlock */
private final ReentrantReadWriteLock.ReadLock readerLock;
/** Inner class providing writelock */
private final ReentrantReadWriteLock.WriteLock writerLock;
/** Performs all synchronization mechanics */
final Sync sync;
public ReentrantReadWriteLock() {
this(false);
}
public ReentrantReadWriteLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
readerLock = new ReadLock(this);
writerLock = new WriteLock(this);
}
public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 6317671515068378041L;
static final int SHARED_SHIFT = 16;
// 00000000 00000001 00000000 00000000
//每获取一个共享锁加一个SHARED_UNIT(其实就是高16位累加1)
static final int SHARED_UNIT = (1 << SHARED_SHIFT);
// 00000000 00000000 11111111 11111111
static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;
// 00000000 00000000 11111111 11111111
static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
//高16位存放共享锁个数
static int sharedCount(int c) { return c >>> SHARED_SHIFT; }
//低16位存放独占锁个数
static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
//用于统计每个线程获取共享锁的个数,有什么作用:
//一个线程获取了读(共享)锁那么其它线程获取写锁时会等待,此时再写等待线程之后如果有线程
//想获取读锁时分两种情况:
//1.这个线程第一次获取读锁(count值是0),那么将获取失败进行等待
//2.这个线程已至少获取过一次读锁(count大于等于1),那么当前线程可以获取到读锁。
static final class HoldCounter {
int count = 0;
// Use id, not reference, to avoid garbage retention
final long tid = getThreadId(Thread.currentThread());
}
//继承ThreadLocal保证每个线程计数器都是唯一副本
static final class ThreadLocalHoldCounter
extends ThreadLocal<HoldCounter> {
public HoldCounter initialValue() {
return new HoldCounter();
}
}
private transient ThreadLocalHoldCounter readHolds;
private transient HoldCounter cachedHoldCounter;
//第一个获取读锁的线程,作用只是为了快捷返回
private transient Thread firstReader = null;
//第一个获取读锁的线程锁持有锁的次数
private transient int firstReaderHoldCount;
Sync() {
readHolds = new ThreadLocalHoldCounter();
setState(getState()); // ensures visibility of readHolds
}
abstract boolean readerShouldBlock();
abstract boolean writerShouldBlock();
//释放写锁
protected final boolean tryRelease(int releases) {
//当前线程必须持有写锁
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
int nextc = getState() - releases;
//同一个线程可以多次持有写锁,直达全部释放时写锁才算释放
boolean free = exclusiveCount(nextc) == 0;
if (free)
setExclusiveOwnerThread(null);
setState(nextc);
return free;
}
//获取一个独占锁(写锁)
protected final boolean tryAcquire(int acquires) {
Thread current = Thread.currentThread();
int c = getState();
int w = exclusiveCount(c);//查看低16位独占锁的个数
if (c != 0) {//不为0说明有共享锁或独占锁
// (Note: if c != 0 and w == 0 then shared count != 0)
//c不等于w等于0说明有共享锁,此时不允许再获取独占锁(即使当前线程已经获取了共享锁也不允许再获取独占锁)
if (w == 0 || current != getExclusiveOwnerThread())
return false;
//只有独占锁且占有锁的线程就是当前线程,返回成功(同一个获取锁的线程可以多次获取)
if (w + exclusiveCount(acquires) > MAX_COUNT)
throw new Error("Maximum lock count exceeded");
// Reentrant acquire
//由于当前线程已经拥有独占锁,因此其它线程不可能修改state,这里直接赋值是安全的
setState(c + acquires);
return true;
}
//writerShouldBlock在非公平模式下总是false,而在公平模式下用于判断等待队列中是否有
//线程在排队,如果有则直接返回false。非公平模式直接比较设置,设置成功就返回true否则false,
//不礼让先排队的线程
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
return false;
setExclusiveOwnerThread(current);
return true;
}
//释放读锁,每次只释放一个锁,因此unused未使用
protected final boolean tryReleaseShared(int unused) {
Thread current = Thread.currentThread();
//如果当前线程就是第一个获取读锁的线程,直接修改相关属性
if (firstReader == current) {
// assert firstReaderHoldCount > 0;
if (firstReaderHoldCount == 1)
firstReader = null;
else
firstReaderHoldCount--;
} else {
//如果不是获取相关线程的计数器进行相关属性的设置
HoldCounter rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current))
rh = readHolds.get();
int count = rh.count;
//锁计数器清零后直接删除当前线程的计数副本
if (count <= 1) {
readHolds.remove();
if (count <= 0)
throw unmatchedUnlockException();
}
--rh.count;
}
for (;;) {
int c = getState();
int nextc = c - SHARED_UNIT;
//自旋知道设置成功为止
if (compareAndSetState(c, nextc))
//只有共享和或独占都清零时(返回true)才释放等待的线程
//否则返回false,不释放正在等待的线程
return nextc == 0;
}
}
private IllegalMonitorStateException unmatchedUnlockException() {
return new IllegalMonitorStateException(
"attempt to unlock read lock, not locked by current thread");
}
//每次获取一个读锁,unused未使用
protected final int tryAcquireShared(int unused) {
Thread current = Thread.currentThread();
//state高16位存放共享锁个数,低16位存放独占锁个数
int c = getState();
//看低16独占锁的个数是否是0
//必须独占锁个数是0或者独占锁的线程和当前获取共享锁的线程是同一个才允许剩余操作
if (exclusiveCount(c) != 0 &&
getExclusiveOwnerThread() != current)
return -1;//只要有写锁,必定无法获取读锁
//注意!!上面if分支透露出当前线程获取了写锁可以再获取读锁
int r = sharedCount(c);
//判断是否该阻塞共享锁获取
//1.公平模式下判断等待队列中是否有线程排队,如果有readerShouldBlock返回true
//2.非公平模式下判断等待队列中第一个等待的线程(队列头部位置)是否是独占模式,是,返回true
if (!readerShouldBlock() &&
r < MAX_COUNT &&//已有的共享锁数量不能超过最大值65535
compareAndSetState(c, c + SHARED_UNIT)) {//高16位累加1
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);
}
final int fullTryAcquireShared(Thread current) {
HoldCounter rh = null;
for (;;) {
int c = getState();
if (exclusiveCount(c) != 0) {//同一个线程获取了写锁可以再次获取读锁
if (getExclusiveOwnerThread() != current)
//已有线程获取独占锁且和当前请求共享锁的线程不同,则返回-1
return -1;
// else we hold the exclusive lock; blocking here
// would cause deadlock.
} else if (readerShouldBlock()) {
//如果此时等待队列中有线程等待,那么说明
//1.当前线程获取了写锁再获取读锁,等待队列中是读线程或写线程
//2.有共享线程获取了锁等待队列中有写线程
// 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();
}
}
//这里count是0会返回-1,为什么?
//这个线程想获取共享锁,但是等待队列中已经有线程等待锁了,那么看看这个线程是否是第一次请求
//共享锁(count是0),是第一次那么直接返回-1否则走下面流程(之前已经获取过共享锁,再次获取应当优先于等待队列中的线程)
if (rh.count == 0)
//1.从这里看出,只要等待队列中有写线程,那么新来的读线程必须等待
//2.当前线程已经获取了写锁再获取读锁,但发现队列中已经有线程等待读/写,那么此时当前线程也不允许获取读锁
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;
}
}
}
//尝试获取写锁
final boolean tryWriteLock() {
Thread current = Thread.currentThread();
int c = getState();
if (c != 0) {
int w = exclusiveCount(c);
if (w == 0 || current != getExclusiveOwnerThread())
return false;
if (w == MAX_COUNT)
throw new Error("Maximum lock count exceeded");
}
//1.如果还没有线程获取过锁,尝试比较设置,成功返回
//2.当前线程已获得了写锁再次获取
if (!compareAndSetState(c, c + 1))
return false;
setExclusiveOwnerThread(current);
return true;
}
//尝试获取读锁
final boolean tryReadLock() {
Thread current = Thread.currentThread();
//放到死循环中,只要有其它线程获取了写锁,会直接返回false,否则总能获取到读锁并返回
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
//根据状态值再返回getExclusiveOwnerThread,因为报错线程是属性exclusiveOwnerThread没有声明volatile,可能不可见
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;
}
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(); }
}
/**
* Nonfair version of Sync
*/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = -8159625535654395037L;
//由tryAcquire中调用,非公平模式直接使用比较设置来抢占锁
final boolean writerShouldBlock() {//方法名理解为是否写公平
return false; // writers can always barge
}
//由fullTryAcquireShared调用,只要头一个等待节点不是独占的,则使用比较设置抢占锁
final boolean readerShouldBlock() {//方法名理解为是否读公平
return apparentlyFirstQueuedIsExclusive();
}
}
static final class FairSync extends Sync {
private static final long serialVersionUID = -2274990926593161451L;
//由tryAcquire中调用,公平模式下发现有线程在等待那么久不允许获取
final boolean writerShouldBlock() {
return hasQueuedPredecessors();
}
//由fullTryAcquireShared调用,公平模式下发现有线程在等待那么久不允许获取
final boolean readerShouldBlock() {
return hasQueuedPredecessors();
}
}
public static class ReadLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = -5992448646407690164L;
private final Sync sync;
protected ReadLock(ReentrantReadWriteLock lock) {
sync = lock.sync;
}
public void lock() {
sync.acquireShared(1);
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public boolean tryLock() {
return sync.tryReadLock();
}
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
public void unlock() {
sync.releaseShared(1);
}
//共享锁不支持Condition
public Condition newCondition() {
throw new UnsupportedOperationException();
}
public String toString() {
int r = sync.getReadLockCount();
return super.toString() +
"[Read locks = " + r + "]";
}
}
public static class WriteLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = -4992448646407690164L;
private final Sync sync;
protected WriteLock(ReentrantReadWriteLock lock) {
sync = lock.sync;
}
//获取一个写锁
public void lock() {
sync.acquire(1);
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock( ) {
return sync.tryWriteLock();
}
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
public void unlock() {
sync.release(1);
}
//只有些锁(独占)支持Condition
public Condition newCondition() {
return sync.newCondition();
}
public String toString() {
Thread o = sync.getOwner();
return super.toString() + ((o == null) ?
"[Unlocked]" :
"[Locked by thread " + o.getName() + "]");
}
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
public int getHoldCount() {
return sync.getWriteHoldCount();
}
}
public final boolean isFair() {
return sync instanceof FairSync;
}
protected Thread getOwner() {
return sync.getOwner();
}
public int getReadLockCount() {
return sync.getReadLockCount();
}
public boolean isWriteLocked() {
return sync.isWriteLocked();
}
public boolean isWriteLockedByCurrentThread() {
return sync.isHeldExclusively();
}
public int getWriteHoldCount() {
return sync.getWriteHoldCount();
}
public int getReadHoldCount() {
return sync.getReadHoldCount();
}
protected Collection<Thread> getQueuedWriterThreads() {
return sync.getExclusiveQueuedThreads();
}
protected Collection<Thread> getQueuedReaderThreads() {
return sync.getSharedQueuedThreads();
}
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
public final boolean hasQueuedThread(Thread thread) {
return sync.isQueued(thread);
}
public final int getQueueLength() {
return sync.getQueueLength();
}
protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
}
public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
}
protected Collection<Thread> getWaitingThreads(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
}
public String toString() {
int c = sync.getCount();
int w = Sync.exclusiveCount(c);
int r = Sync.sharedCount(c);
return super.toString() +
"[Write locks = " + w + ", Read locks = " + r + "]";
}
static final long getThreadId(Thread thread) {
return UNSAFE.getLongVolatile(thread, TID_OFFSET);
}
// Unsafe mechanics
private static final sun.misc.Unsafe UNSAFE;
private static final long TID_OFFSET;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> tk = Thread.class;
TID_OFFSET = UNSAFE.objectFieldOffset
(tk.getDeclaredField("tid"));
} catch (Exception e) {
throw new Error(e);
}
}
}