@SuppressWarnings("restriction")
public class ReentrantReadWriteLock1 implements ReadWriteLock, java.io.Serializable {
private static final long serialVersionUID = -6992448646407690164L;
private final ReentrantReadWriteLock1.ReadLock readerLock;
private final ReentrantReadWriteLock1.WriteLock writerLock;
final Sync sync;
public ReentrantReadWriteLock1() {
this(false);
}
public ReentrantReadWriteLock1(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
readerLock = new ReadLock(this);//写锁和读锁,公用同一个Sync,也就是同一个AQS队列,
writerLock = new WriteLock(this);
}
public ReentrantReadWriteLock1.WriteLock writeLock() {
return writerLock;
}
public ReentrantReadWriteLock1.ReadLock readLock() {
return readerLock;
}
abstract static class Sync extends AbstractQueuedSynchronizer1 {//ReentrantLock有自己的Sync,都继承AQS类,
private static final long serialVersionUID = 6317671515068378041L;
static final int SHARED_SHIFT = 16;
static final int SHARED_UNIT = (1 << SHARED_SHIFT);// 2^16
static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;// 2^16-1
static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;// 2^16-1
static int sharedCount(int c) {//小于2^16=0,等于2^16=1,大于2^16>1,共享锁最大共享线程数=2^16-1,
return c >>> SHARED_SHIFT;// 右移16位,
}
static int exclusiveCount(int c) {
return c & EXCLUSIVE_MASK;// 去掉前面16位,
}
static final class HoldCounter {
int count = 0;
final long tid = getThreadId(Thread.currentThread());
}
static final class ThreadLocalHoldCounter extends ThreadLocal<HoldCounter> {
public HoldCounter initialValue() {
return new HoldCounter();//ThreadLocalHoldCounter作为key,new HoldCounter()作为value,
}
}
//当前线程持有的可重入读锁的数量。构造函数中初始化。每当线程的读计数下降到0时删除。
private transient ThreadLocalHoldCounter readHolds;//只有一个
private transient HoldCounter cachedHoldCounter;//多个
private transient Thread firstReader = null;
private transient int firstReaderHoldCount;
Sync() {
readHolds = new ThreadLocalHoldCounter();//只有一个
setState(getState());
}
abstract boolean readerShouldBlock();
abstract boolean writerShouldBlock();
protected final boolean tryRelease(int releases) {//写锁释放
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
int nextc = getState() - releases;// 状态变量的值减1
boolean free = exclusiveCount(nextc) == 0;//写锁=0
if (free)//getState()-releases == 0
setExclusiveOwnerThread(null);
setState(nextc);
return free;
}
protected final boolean tryAcquire(int acquires) {//WriteLock获取锁,多线程访问
Thread current = Thread.currentThread();
int c = getState();
int w = exclusiveCount(c);//w=0则C=2^16,w!=0则C<2^16,写锁被获取的次数
if (c != 0) {//锁里面有线程了重入锁,写锁只要看见state里面有线程就去排队(可能里面有读锁或者写锁),
// c!=0,w=0:说明C=2^16的整数倍,说明有读线程获取了锁,
if (w == 0 || current != getExclusiveOwnerThread()) // c!=0,w=0,说明有读锁进去,写锁不进去,其它线程获取了互斥锁(写锁)
return false;//获取锁失败去排队
/*单线程进来,线程安全的。 */
//w!=0&¤t=OwnerThread,MAX_COUNT=2^16-1,就去加值,
if (w + exclusiveCount(acquires) > MAX_COUNT)
throw new Error("Maximum lock count exceeded");
//w!=0&¤t=OwnerThread,MAX_COUNT=2^16-1,就去加值,
setState(c + acquires);//acquires每次都是从1开始的,C从0开始,所以c,w,acquires不可能大于2^16。
return true;
}
//c=0,锁里面没有线程,就要去抢锁。
//writerShouldBlock:非公平返回false,就去获取锁。
//writerShouldBlock:公平,返回true排队,返回false,就去获取锁。
//获取state成功设置owenerThread=自己,不去排队,获取state失败,去排队。
if (writerShouldBlock() || !compareAndSetState(c, c + acquires))
return false;
/*单线程进来,线程安全的。
compareAndSetState(c, c+acquires)可以作为一把锁,synchronized,
别的线程要想进到compareAndSetState包裹的代码里面去,必须重新获取新的c=c+acquires,但是进去if(c!=0)里面去了。
*/
setExclusiveOwnerThread(current);//获得锁。
return true;
}
protected final boolean tryReleaseShared(int unused) {// 读锁释放(共享锁),unused没有使用
Thread current = Thread.currentThread();
if (firstReader == current) {
// 如果第一个读者(读线程)是当前线程
// 就把它重入的次数减1
// 如果减到0了就把第一个读者置为空
if (firstReaderHoldCount == 1)
firstReader = null;
else
firstReaderHoldCount--;
} else {
// 如果第一个读者不是当前线程,一样地,把它重入的次数减1
HoldCounter rh = cachedHoldCounter;//最后获取读锁的HoldCounter
if (rh == null || rh.tid != getThreadId(current))
rh = readHolds.get();//get方法没有时候,就回去创建,有就返回。返回当前线程threadLcoalMap里面的那行记录
int count = rh.count;
if (count <= 1) {
readHolds.remove();
if (count <= 0)
throw unmatchedUnlockException();
}
--rh.count;
}
for (;;) {// 共享锁获取的次数减1,如果减为0了说明完全释放了,才返回true
int c = getState();
int nextc = c - SHARED_UNIT;//减去65536
if (compareAndSetState(c, nextc))
return nextc == 0;//读锁完全释放了,
}
}
private IllegalMonitorStateException unmatchedUnlockException() {
return new IllegalMonitorStateException("attempt to unlock read lock, not locked by current thread");
}
//读锁每次进来加65536,写锁每次进来加1,
protected final int tryAcquireShared(int unused) {//ReadLock获取锁,走这个方法,并发问题,unused没有使用
// 在读写锁模式下,高16位存储的是共享锁(读锁)被获取的次数,低16位存储的是互斥锁(写锁)被获取的次数
Thread current = Thread.currentThread();
int c = getState();//state在AQS类里面,读锁写锁,公用一个Sync AQS state,写锁只能一个进去,另一个写锁进不去,读锁也进不去,
if (exclusiveCount(c) != 0 /*去掉前面16位,*/ && getExclusiveOwnerThread() != current)//state!=0,并且 当前线程没有获取锁。如果写线程获取了锁,state+1就返回-1去排队。
return -1;
int r = sharedCount(c);//右移16位, 读锁被获取的次数
//多线程可以进来
if (!readerShouldBlock()/* AQS队列第一个节点写线程跳过,没有第一个节点或者第一个是读线程就进去 */ && r < MAX_COUNT
&& compareAndSetState(c, c + SHARED_UNIT)/* c每次增加65536 */) {
//可以多线程进来,AQS队列没有节点 并且 c是2^16的整数倍=0就是没有写锁,第一个线程进来后只要后面的线程重新获取c就可以进来,
// 注意下面对firstReader的处理:firstReader是不会放到readHolds里的
// 这样,在读锁只有一个的情况下,就避免了查找readHolds。
if (r == 0) {//r=0,c<2^16,没有读锁
firstReader = current;//获取读锁的线程,Thread
firstReaderHoldCount = 1;
} else if (firstReader == current) {//重入锁
firstReaderHoldCount++;
} else {
//先查缓存
HoldCounter rh = cachedHoldCounter;//HoldCounter,缓存前一个线程的HoldCounter(线程id和获取锁次数)
if (rh == null || rh.tid != getThreadId(current))
//ThreadLocal里面get,ThreadLocalHoldCounter。
//当前线程的threadLocals属性的threadLocalMap里面加了一行记录(key=readHolds[ThreadLocalHoldCounter],value=cachedHoldCounter[HoldCounter]),
//其他线程也会在他的threadLocals的threadLocalMap里面加一行记录(key=readHolds[ThreadLocalHoldCounter],value=cachedHoldCounter[HoldCounter]),
//每个线程里面只有一行记录,ThreadLocal是公用的,因为只有一个ThreadLocal,value放的是线程的id和计数器。就这样线程就获取了锁,
cachedHoldCounter = rh = readHolds.get();
else if (rh.count == 0)//当前线程就是上一次线程,就修改thradLocals
readHolds.set(rh);
rh.count++;//多个读,只有一个firstReader,其余的都是在线程里面的threadLocals里面加了一行记录,重入的次数加1(初始次数为0)
}
return 1;//获取了锁
}
//有人在排队
return fullTryAcquireShared(current);
}
//在tryAcquireShared中经行了一次快速锁获取,但是由于CAS只能允许一个线程获取锁成功,且读锁是共享的,
//可能存在其他仍然可以获取锁的线程,所以在函数末尾调用函数fullTryAcquireShared来进行死循环的获取锁,
final int fullTryAcquireShared(Thread current) {//获取读锁
HoldCounter rh = null;
for (;;) {//死循环
int c = getState();
if (exclusiveCount(c) != 0) {//去掉前面16位!= 0
if (getExclusiveOwnerThread() != current)//相等,就是先获取写锁在获取读锁,
return -1;//排队
// 否则,我们持有独占锁;在这里阻塞将导致死锁。
} else if (readerShouldBlock()) {//去掉前面16位= 0,并且AQS队列有第一个节点是写锁不是读锁,
// 确保我们没有重新获取读锁
if (firstReader == current) {
// assert firstReaderHoldCount > 0;
} else {
if (rh == null) {
rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current)) {
rh = readHolds.get();//设置当前线程的threadLocals,key还是readHolds同一个ThreadLocal,
if (rh.count == 0)//!=0,就说明这个线程之前已经获取一次锁成功了,
readHolds.remove();//从当前线程threadLocals中移除这行记录,
}
}
if (rh.count == 0)
return -1;//排队,
}
}
//AQS没有节点,有第一个节点,第一个节点只能是读节点,就去设置threadLcoalMap并且获取锁,
if (sharedCount(c) == MAX_COUNT)
throw new Error("Maximum lock count exceeded");
if (compareAndSetState(c, c + SHARED_UNIT)) {
if (sharedCount(c) == 0) {//=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");
}
//c=0
if (!compareAndSetState(c, c + 1))
return false;
setExclusiveOwnerThread(current);
return true;
}
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() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
final ConditionObject newCondition() {
return new ConditionObject();
}
final Thread getOwner() {
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();
}
}
static final class NonfairSync extends Sync {
private static final long serialVersionUID = -8159625535654395037L;
final boolean writerShouldBlock() {//false获取锁。
return false;
}
final boolean readerShouldBlock() {// 非公平读是否要阻塞,true排队,false获取锁。
return apparentlyFirstQueuedIsExclusive();//AQS队列有第一个节点是写锁不是读锁,
}
}
static final class FairSync extends Sync {
private static final long serialVersionUID = -2274990926593161451L;
final boolean writerShouldBlock() {// 公平写是否要阻塞,true排队,false获取锁。
return hasQueuedPredecessors();
}
final boolean readerShouldBlock() {// 公平读是否要阻塞,true排队,false获取锁。
return hasQueuedPredecessors();
}
}
public static class ReadLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = -5992448646407690164L;
private final Sync sync;
protected ReadLock(ReentrantReadWriteLock1 lock) {// 外部类this
sync = lock.sync;
}
public void lock() {//获取读锁,获取的是共享锁,调用sync.acquireShared(AQS的方法),写锁调用sync.acquire(AQS的方法)
try {
sync.acquireShared(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
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);
}
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(ReentrantReadWriteLock1 lock) {
sync = lock.sync;
}
public void lock() {//获取写锁,写锁的获取逻辑和ReentrantLock一样,失败的加入AQS队列,
try {//读锁调用sync.acquireShared(AQS的方法),写锁调用sync.acquire(AQS的方法)
sync.acquire(1);//尝试获取锁,获取失败就在AQS阻塞排队
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock() {
return sync.tryWriteLock();//获取读锁,不在AQS类里面,在本Sync类里面,
}
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
public void unlock() {
sync.release(1);//写锁释放,线程安全,唤醒AQS头结点,
}
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 AbstractQueuedSynchronizer1.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer1.ConditionObject) condition);
}
public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer1.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer1.ConditionObject) condition);
}
protected Collection<Thread> getWaitingThreads(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer1.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer1.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 + "]";
}
// Thread Id可以被重写
static final long getThreadId(Thread thread) {
return UNSAFE.getLongVolatile(thread, TID_OFFSET);
}
private static final sun.misc.Unsafe UNSAFE;
private static final long TID_OFFSET;
static {
try {
UNSAFE = java.security.AccessController
.doPrivileged(new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
public sun.misc.Unsafe run() throws Exception {
Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
for (java.lang.reflect.Field f : k.getDeclaredFields()) {
f.setAccessible(true);
Object x = f.get(null);
if (k.isInstance(x))
return k.cast(x);
}
throw new NoSuchFieldError("the Unsafe");
}
});
Class<?> tk = Thread.class;
TID_OFFSET = UNSAFE.objectFieldOffset(tk.getDeclaredField("tid"));
} catch (Exception e) {
throw new Error(e);
}
}
}