ReentrantReadWriteLock源码
@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); } } }