/* * * 赵泉伟原创,转载请注明出处,谢谢! */ package com.example.demo; import java.util.concurrent.TimeUnit; import java.util.Collection; import java.util.concurrent.locks.AbstractQueuedSynchronizer; 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; /** * Creates a new {@code ReentrantReadWriteLock} with * default (nonfair) ordering properties. */ public ReentrantReadWriteLock() {//默认无参构造器 this(false);//默认调用有参构造器 ,参数为是否公平锁模式,默认为false,即非公平锁模式 } /** * Creates a new {@code ReentrantReadWriteLock} with * the given fairness policy. * * @param fair {@code true} if this lock should use a fair ordering policy */ public ReentrantReadWriteLock(boolean fair) {//有参构造器,参数为boolean类型,是否公平锁模式 sync = fair ? new FairSync() : new NonfairSync();//如果为true则 创建公平锁模式对象,否则为非公平锁模式 readerLock = new ReadLock(this);//构建读锁对象 writerLock = new WriteLock(this);//构建写锁对象 } 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 {//定义抽象静态内部类Sync继承AQS同步器 private static final long serialVersionUID = 6317671515068378041L; /* 读写锁共用同步状态变量,来同时维护读和写的状态,同步状态变量是一个int型变量 * 进行按位切割使用,高16位表示读的状态, 低16位表示写的状态 * 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. */ static final int SHARED_SHIFT = 16;//读锁状态偏移位,偏移16位 static final int SHARED_UNIT = (1 << SHARED_SHIFT);//读锁操作的基本单元,读锁状态+1,则状态变量值+SHARED_UNIT 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;//默认为0次 // Use id, not reference, to avoid garbage retention final long tid = getThreadId(Thread.currentThread());//获取当前线程id } /** * ThreadLocal subclass. Easiest to explicitly define for sake * of deserialization mechanics. /** * 继承了ThreadLocal,通过ThreadLocal实现记录线程获取读锁次数的记录 * key是Thread对象的引用,value是HoldCounter对象 * HoldCounter对象中保存了获取读锁次数count,和线程tid */ 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;//保存线程获取读锁的次数 private transient HoldCounter cachedHoldCounter;//当前线程缓存的holdCounter private transient Thread firstReader = null;//第一个获取读锁的线程,默认为null private transient int firstReaderHoldCount;//firstReader获取了多少次读锁 Sync() {//无参构造器 readHolds = new ThreadLocalHoldCounter();//实例化ThreadLocalHoldCounter对象 setState(getState()); // 设定锁的状态 } abstract boolean readerShouldBlock();//读锁是否应该阻塞的抽象方法 abstract boolean writerShouldBlock();//写锁是否应该阻塞的抽象方法 protected final boolean tryRelease(int releases) {//尝试释放锁 if (!isHeldExclusively())//如果false则报错 throw new IllegalMonitorStateException();//抛异常 int nextc = getState() - releases;//否则获取当前锁的状态值 boolean free = exclusiveCount(nextc) == 0;//根据获取的状态值进行计算,如果为0 if (free)//true setExclusiveOwnerThread(null);//将当前持有的锁的线程对象置为null setState(nextc);//重新设定状态值 return free;//返回释放是否成功 } protected final boolean tryAcquire(int acquires) {//尝试获取锁 Thread current = Thread.currentThread();//获取当前线程 int c = getState();//获取当前状态 int w = exclusiveCount(c);//根据状态值进行计算 if (c != 0) {//如果值!=0 if (w == 0 || current != getExclusiveOwnerThread())//锁状态值为0||当前线程不为已持有锁的线程对象 return false;//返回false表示没有获取到锁 if (w + exclusiveCount(acquires) > MAX_COUNT)//如果锁状态值+根据传入的状态值计算后大于可重入的最大值则抛异常 throw new Error("Maximum lock count exceeded");//抛异常 // Reentrant acquire setState(c + acquires);//否则重新设定状态值 return true;//返回true,表示获取锁成功 } if (writerShouldBlock() || !compareAndSetState(c, c + acquires))//判读写锁是否应该阻塞或者当前的状态值内存的是否一致,如果不一致或者应该阻塞,则直接返回false return false;//返回false表示没有获取到锁 setExclusiveOwnerThread(current);//将当前线程设置为已持有锁的线程对象 return true;//返回true,表示获取锁成功 } protected final boolean tryReleaseShared(int unused) {//尝试释放共享锁 Thread current = Thread.currentThread();//获取当前线程对象 if (firstReader == current) {//判读当前线程是不是第一个获取锁的读线程 // assert firstReaderHoldCount > 0; if (firstReaderHoldCount == 1)//如果计数器=1表示只有一个锁了,可以直接进行释放了 firstReader = null;//将第一个获取读锁的线程对象置为null else//否则 firstReaderHoldCount--;//自减 } else {//如果当前线程不是第一个获取锁的读线程 HoldCounter rh = cachedHoldCounter;//获取当前线程缓存的holdCounter if (rh == null || rh.tid != getThreadId(current))//如果缓存对象为空||缓存的线程id!=当前线程id rh = readHolds.get();//则从保存的ThreadLocal对象里获取的返回线程保存的读锁对象 int count = rh.count;//获取读锁次数 if (count <= 1) {//如果读锁次数<=1 readHolds.remove();//从ThreadLocal对象移除该读锁对象 if (count <= 0)//如果<=0则抛异常 throw unmatchedUnlockException();//抛异常 } --rh.count;//否则自减 } for (;;) {//自旋 int c = getState();//获取当前状态 int nextc = c - SHARED_UNIT;//计算状态值 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) {//尝试获取共享锁 Thread current = Thread.currentThread();//获取当前线程对象 int c = getState();//获取当前状态值 if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current)//写锁状态值不为0并且已持有锁的线程对象不是当前线程 return -1;//返回-1表示获取锁失败 int r = sharedCount(c);//计算读锁状态值 if (!readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) {//判断是否应该阻塞并且计算的状态值小于阈值并且更新内存里的状态成功 if (r == 0) {//如果获取到的读锁状态值为0 firstReader = current;//将当前线程对象设置为一个获取到锁的读线程 firstReaderHoldCount = 1;//将读锁的获取次数置为1 } else if (firstReader == current) {//如果第一个获取锁的线程为当前线程 firstReaderHoldCount++;//则读锁次数自增 } else {//否则 HoldCounter rh = cachedHoldCounter;//获取线程缓存的holdCounter if (rh == null || rh.tid != getThreadId(current))//如果缓存为空或者缓存的线程id不等于当前线程的id cachedHoldCounter = rh = readHolds.get();//根据当前线程对象从ThreadLocal中获取HoldCounter对象并赋值给缓存对象 else if (rh.count == 0)//如果获取到的缓存线程的holdCounter计数器为0 readHolds.set(rh);//将该holdCounter设置为当前线程对应的holdCounter对象 rh.count++;//计数器自增 } return 1;//返回获取锁成功 } return fullTryAcquireShared(current);//否则进行尝试循环来获取锁 } final int fullTryAcquireShared(Thread current) {//尝试循环来获取锁 HoldCounter rh = null;//定义一个HoldCounter对象 for (;;) {//自旋 int c = getState();//获取当前状态 if (exclusiveCount(c) != 0) {//如果计算出来的锁状态值不为0 /** * 如果是其他线程获取了写锁,那么把当前线程阻塞 * 如果是当前线程获取了写锁,不阻塞,否则会造成死锁 * 从这里可以看到ReentrantReadWriteLock允许锁降级 */ if (getExclusiveOwnerThread() != current)//并且锁持有的线程对象不是当前线程对象 return -1;//则返回-1表示获取锁失败 } else if (readerShouldBlock()) {//判断读锁是否应该阻塞 /** * 进入这里说明,同步队列的头结点的后继有一个竞争写锁的线程 * 所以这里有一个锁让步的操作,即让写锁先获取 * 如果是firstReader必然是重入,或者rh.count>0也必然是重入 * 对于读锁重入是允许死循环直到获取锁成功的,不然会导致死锁 * 但是如果rh.count = 0就说明,这个线程是第一次获取读锁 * 为了防止写饥饿,直接将他们重新扔会同步队列,而且这些阻塞不会导致死锁 */ if (firstReader == current) {//判断第一个获取读锁的线程对象是否等于当前线程对象 // assert firstReaderHoldCount > 0; } else {//如果不是 if (rh == null) {//如果定义一个HoldCounter对象为空null rh = cachedHoldCounter;//则将HoldCounter初始化为缓存的HoldCounter对象 if (rh == null || rh.tid != getThreadId(current)) {//如果为空或者缓存的线程id不等于当前线程id rh = readHolds.get();//根据当前线程对象从ThreadLocal里获取读锁的HoldCounter对象 if (rh.count == 0)//如果HoldCounter的线程计数器为0 readHolds.remove();//则将其从ThreadLocal移除 } } if (rh.count == 0)//如果线程计数器为0 return -1;//则返回-1表示获取锁失败 } } 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;//将读锁线程计数器置为1 } else if (firstReader == current) {//如果当前线程为第一次获取到的读锁线程对象 firstReaderHoldCount++;//则读锁线程计数器自增 } else {//否则 if (rh == null)//如果HoldCount对象为null rh = cachedHoldCounter;//将缓存的对象作为HoldCount if (rh == null || rh.tid != getThreadId(current))//如果为null或者线程id不是当前线程id rh = readHolds.get();//根据当前线程对象从ThreadLocal中取出HoldCount对象 else if (rh.count == 0)//如果计数器为0 readHolds.set(rh);//将HoldCount置为当前线程的HoldCount对象 rh.count++;//线程计数器自增 cachedHoldCounter = rh; // 将当前HoldCount对象置为缓存对象 } 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) {//如果不为0 int w = exclusiveCount(c);//计算写锁的状态值 if (w == 0 || current != getExclusiveOwnerThread())//如果为0或当前前程不是已持有锁的线程 return false;//返回false if (w == MAX_COUNT)//如果值等于最大可重入数 throw new Error("Maximum lock count exceeded");//抛异常 } if (!compareAndSetState(c, c + 1))//更新最新状态值失败 return false;//返回false setExclusiveOwnerThread(current);//将当前线程更新为已持有锁的线程 return true;//返回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 &&//如果写锁状态值不为0并且当前线程不为已持有锁的线程 getExclusiveOwnerThread() != current) return false;//返回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) {//如果为0 firstReader = current;//将当前线程对象置为第一个获取到读锁的线程对象 firstReaderHoldCount = 1;//计数器为1 } else if (firstReader == current) {//如果当前线程对象不为第一个获取到读锁的线程对象 firstReaderHoldCount++;//则计数器自增 } else {//否则 HoldCounter rh = cachedHoldCounter;//从缓存里获取HoldCounter对象 if (rh == null || rh.tid != getThreadId(current))//如果为null或者线程对象id不为当前线程对象id cachedHoldCounter = rh = readHolds.get();//根据当前线程对象从ThreadLocal里获取HoldCounter对象 else if (rh.count == 0)//如果计数器为0表示第一次获取锁 readHolds.set(rh);//将当前HoldCounter置为当前线程的HoldCounter对象 rh.count++;//计数器自增 } return true;//返回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() {//返回新的ConditionObject队列对象 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)//为0 return 0;//则返回0 Thread current = Thread.currentThread();//获取当前线程对象 if (firstReader == current)//如果当前线程为第一个获取读锁的线程持有的线程对象 return firstReaderHoldCount;//直接返回 HoldCounter rh = cachedHoldCounter;//从缓存里获取HoldCounter if (rh != null && rh.tid == getThreadId(current))//如果不为空并且HoldCounter的线程id等于当前线程id return rh.count;//将计数器count对象返回 int count = readHolds.get().count;//否则根据当前线程对象从ThreadLocal里获取并返回count if (count == 0) readHolds.remove();//如果数量为0,则从ThreadLocal里移除 return count;//返回对应的count } /** * Reconstitutes the instance from a stream (that is, deserializes it). */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {//初始化ThreadLocalHoldCounter对象 s.defaultReadObject(); readHolds = new ThreadLocalHoldCounter(); setState(0); // 初始化锁状态 } final int getCount() { return getState(); }//返回锁的状态 } /** * Nonfair version of Sync */ static final class NonfairSync extends Sync {//非公平锁内部类 private static final long serialVersionUID = -8159625535654395037L; final boolean writerShouldBlock() {//是否应该阻塞写锁 return false; // 默认返回false } final boolean readerShouldBlock() {//是否应该阻塞读锁 return apparentlyFirstQueuedIsExclusive();//根据当前读锁的相应状态来判断是否应该阻塞 } } /** * 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();//根据当前读锁的相应状态来判断是否应该阻塞 } } /** * The lock returned by method {@link ReentrantReadWriteLock#readLock}. */ public static class ReadLock implements Lock, java.io.Serializable { private static final long serialVersionUID = -5992448646407690164L; private final Sync sync; /** * Constructor for use by subclasses * * @param lock the outer lock object * @throws NullPointerException if the lock is null */ protected ReadLock(ReentrantReadWriteLock lock) {//注入是否为公平锁 sync = lock.sync; } /** * Acquires the read lock. * * <p>Acquires the read lock if the write lock is not held by * another thread and returns immediately. * * <p>If the write lock is held by another thread then * the current thread becomes disabled for thread scheduling * purposes and lies dormant until the read lock has been acquired. */ public void lock() {//调用AQS同步器加锁 sync.acquireShared(1); } public void lockInterruptibly() throws InterruptedException {//调用AQS同步器进行中断 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));//调用AQS同步器里对应的方法 } /** * Attempts to release this lock. * * <p>If the number of readers is now zero then the lock * is made available for write lock attempts. */ public void unlock() {//释放锁 sync.releaseShared(1);//调用AQS同步器里的释放锁方法 } /** * Throws {@code UnsupportedOperationException} because * {@code ReadLocks} do not support conditions. * * @throws UnsupportedOperationException always */ public Condition newCondition() {//声明一个创建Condition的方法,如果没有重写该方法则抛异常 throw new UnsupportedOperationException();//抛异常 } public String toString() {//重写toString方法 int r = sync.getReadLockCount(); return super.toString() + "[Read locks = " + r + "]"; } } /** * The lock returned by method {@link ReentrantReadWriteLock#writeLock}. */ public static class WriteLock implements Lock, java.io.Serializable {//写锁对象内部类 private static final long serialVersionUID = -4992448646407690164L; private final Sync sync; /** * Constructor for use by subclasses * * @param lock the outer lock object * @throws NullPointerException if the lock is null */ protected WriteLock(ReentrantReadWriteLock lock) {//注入是否公平锁对象 sync = lock.sync; } /** * Acquires the write lock. * * <p>Acquires the write lock if neither the read nor write lock * are held by another thread * and returns immediately, setting the write lock hold count to * one. * * <p>If the current thread already holds the write lock then the * hold count is incremented by one and the method returns * immediately. * * <p>If the lock is held by another thread then the current * thread becomes disabled for thread scheduling purposes and * lies dormant until the write lock has been acquired, at which * time the write lock hold count is set to one. */ public void lock() {//加锁 sync.acquire(1);//调用AQS同步器获取锁方法进行加锁 } /** * Acquires the write lock unless the current thread is * {@linkplain Thread#interrupt interrupted}. * * <p>Acquires the write lock if neither the read nor write lock * are held by another thread * and returns immediately, setting the write lock hold count to * one. * * <p>If the current thread already holds this lock then the * hold count is incremented by one and the method returns * immediately. * * <p>If the lock is held by another thread then the current * thread becomes disabled for thread scheduling purposes and * lies dormant until one of two things happens: * * <ul> * * <li>The write lock is acquired by the current thread; or * * <li>Some other thread {@linkplain Thread#interrupt interrupts} * the current thread. * * </ul> * * <p>If the write lock is acquired by the current thread then the * lock hold count is set to one. * * <p>If the current thread: * * <ul> * * <li>has its interrupted status set on entry to this method; * or * * <li>is {@linkplain Thread#interrupt interrupted} while * acquiring the write lock, * * </ul> * * then {@link InterruptedException} is thrown and the current * thread's interrupted status is cleared. * * <p>In this implementation, as this method is an explicit * interruption point, preference is given to responding to * the interrupt over normal or reentrant acquisition of the * lock. * * @throws InterruptedException if the current thread is interrupted */ public void lockInterruptibly() throws InterruptedException {//获取锁的时候是否响应中断 sync.acquireInterruptibly(1);//调用AQS同步器中断方法 } /** * Acquires the write lock only if it is not held by another thread * at the time of invocation. * * <p>Acquires the write lock if neither the read nor write lock * are held by another thread * and returns immediately with the value {@code true}, * setting the write lock hold count to one. Even when this lock has * been set to use a fair ordering policy, a call to * {@code tryLock()} <em>will</em> immediately acquire the * lock if it is available, whether or not other threads are * currently waiting for the write lock. This "barging" * behavior can be useful in certain circumstances, even * though it breaks fairness. If you want to honor the * fairness setting for this lock, then use {@link * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } * which is almost equivalent (it also detects interruption). * * <p>If the current thread already holds this lock then the * hold count is incremented by one and the method returns * {@code true}. * * <p>If the lock is held by another thread then this method * will return immediately with the value {@code false}. * * @return {@code true} if the lock was free and was acquired * by the current thread, or the write lock was already held * by the current thread; and {@code false} otherwise. */ public boolean tryLock( ) {//尝试获取写锁 return sync.tryWriteLock();//调用自定义获取写锁的方法 } /** * Acquires the write lock if it is not held by another thread * within the given waiting time and the current thread has * not been {@linkplain Thread#interrupt interrupted}. * * <p>Acquires the write lock if neither the read nor write lock * are held by another thread * and returns immediately with the value {@code true}, * setting the write lock hold count to one. If this lock has been * set to use a fair ordering policy then an available lock * <em>will not</em> be acquired if any other threads are * waiting for the write lock. This is in contrast to the {@link * #tryLock()} method. If you want a timed {@code tryLock} * that does permit barging on a fair lock then combine the * timed and un-timed forms together: * * <pre> {@code * if (lock.tryLock() || * lock.tryLock(timeout, unit)) { * ... * }}</pre> * * <p>If the current thread already holds this lock then the * hold count is incremented by one and the method returns * {@code true}. * * <p>If the lock is held by another thread then the current * thread becomes disabled for thread scheduling purposes and * lies dormant until one of three things happens: * * <ul> * * <li>The write lock is acquired by the current thread; or * * <li>Some other thread {@linkplain Thread#interrupt interrupts} * the current thread; or * * <li>The specified waiting time elapses * * </ul> * * <p>If the write lock is acquired then the value {@code true} is * returned and the write lock hold count is set to one. * * <p>If the current thread: * * <ul> * * <li>has its interrupted status set on entry to this method; * or * * <li>is {@linkplain Thread#interrupt interrupted} while * acquiring the write lock, * * </ul> * * then {@link InterruptedException} is thrown and the current * thread's interrupted status is cleared. * * <p>If the specified waiting time elapses then the value * {@code false} is returned. If the time is less than or * equal to zero, the method will not wait at all. * * <p>In this implementation, as this method is an explicit * interruption point, preference is given to responding to * the interrupt over normal or reentrant acquisition of the * lock, and over reporting the elapse of the waiting time. * * @param timeout the time to wait for the write lock * @param unit the time unit of the timeout argument * * @return {@code true} if the lock was free and was acquired * by the current thread, or the write lock was already held by the * current thread; and {@code false} if the waiting time * elapsed before the lock could be acquired. * * @throws InterruptedException if the current thread is interrupted * @throws NullPointerException if the time unit is null */ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {//根据超时时间来获取锁 return sync.tryAcquireNanos(1, unit.toNanos(timeout));//调用AQS同步器里相关方法 } /** * Attempts to release this lock. * * <p>If the current thread is the holder of this lock then * the hold count is decremented. If the hold count is now * zero then the lock is released. If the current thread is * not the holder of this lock then {@link * IllegalMonitorStateException} is thrown. * * @throws IllegalMonitorStateException if the current thread does not * hold this lock */ public void unlock() {//释放锁 sync.release(1);//调用AQS同步器里是否锁的方法 } /** * Returns a {@link Condition} instance for use with this * {@link Lock} instance. * <p>The returned {@link Condition} instance supports the same * usages as do the {@link Object} monitor methods ({@link * Object#wait() wait}, {@link Object#notify notify}, and {@link * Object#notifyAll notifyAll}) when used with the built-in * monitor lock. * * <ul> * * <li>If this write lock is not held when any {@link * Condition} method is called then an {@link * IllegalMonitorStateException} is thrown. (Read locks are * held independently of write locks, so are not checked or * affected. However it is essentially always an error to * invoke a condition waiting method when the current thread * has also acquired read locks, since other threads that * could unblock it will not be able to acquire the write * lock.) * * <li>When the condition {@linkplain Condition#await() waiting} * methods are called the write lock is released and, before * they return, the write lock is reacquired and the lock hold * count restored to what it was when the method was called. * * <li>If a thread is {@linkplain Thread#interrupt interrupted} while * waiting then the wait will terminate, an {@link * InterruptedException} will be thrown, and the thread's * interrupted status will be cleared. * * <li> Waiting threads are signalled in FIFO order. * * <li>The ordering of lock reacquisition for threads returning * from waiting methods is the same as for threads initially * acquiring the lock, which is in the default case not specified, * but for <em>fair</em> locks favors those threads that have been * waiting the longest. * * </ul> * * @return the Condition object */ public Condition newCondition() {//创建一个获取Condition的方法 return sync.newCondition(); } /** * Returns a string identifying this lock, as well as its lock * state. The state, in brackets includes either the String * {@code "Unlocked"} or the String {@code "Locked by"} * followed by the {@linkplain Thread#getName name} of the owning thread. * * @return a string identifying this lock, as well as its lock state */ public String toString() {//重写toString方法 Thread o = sync.getOwner(); return super.toString() + ((o == null) ? "[Unlocked]" : "[Locked by thread " + o.getName() + "]"); } /** * Queries if this write lock is held by the current thread. * Identical in effect to {@link * ReentrantReadWriteLock#isWriteLockedByCurrentThread}. * * @return {@code true} if the current thread holds this lock and * {@code false} otherwise * @since 1.6 */ public boolean isHeldByCurrentThread() {//判断当前线程对象是否为已占有锁的线程对象 return sync.isHeldExclusively();//调用相关方法 } /** * Queries the number of holds on this write lock by the current * thread. A thread has a hold on a lock for each lock action * that is not matched by an unlock action. Identical in effect * to {@link ReentrantReadWriteLock#getWriteHoldCount}. * * @return the number of holds on this lock by the current thread, * or zero if this lock is not held by the current thread * @since 1.6 */ public int getHoldCount() {//获取写锁的状态值 return sync.getWriteHoldCount();//调用相关方法 } } // Instrumentation and status /** * Returns {@code true} if this lock has fairness set true. * * @return {@code true} if this lock has fairness set true */ public final boolean isFair() {//判断是否公平锁 return sync instanceof FairSync; } /** * Returns the thread that currently owns the write lock, or * {@code null} if not owned. When this method is called by a * thread that is not the owner, the return value reflects a * best-effort approximation of current lock status. For example, * the owner may be momentarily {@code null} even if there are * threads trying to acquire the lock but have not yet done so. * This method is designed to facilitate construction of * subclasses that provide more extensive lock monitoring * facilities. * * @return the owner, or {@code null} if not owned */ protected Thread getOwner() {//获取当前已占有锁的线程对象 return sync.getOwner();//调用相关方法 } /** * Queries the number of read locks held for this lock. This * method is designed for use in monitoring system state, not for * synchronization control. * @return the number of read locks held */ public int getReadLockCount() {//获取读锁的状态值 return sync.getReadLockCount();//调用相关方法 } /** * Queries if the write lock is held by any thread. This method is * designed for use in monitoring system state, not for * synchronization control. * * @return {@code true} if any thread holds the write lock and * {@code false} otherwise */ public boolean isWriteLocked() {//判断写锁是否获得锁 return sync.isWriteLocked();//调用相关方法 } /** * Queries if the write lock is held by the current thread. * * @return {@code true} if the current thread holds the write lock and * {@code false} otherwise */ public boolean isWriteLockedByCurrentThread() { return sync.isHeldExclusively(); } /** * Queries the number of reentrant write holds on this lock by the * current thread. A writer thread has a hold on a lock for * each lock action that is not matched by an unlock action. * * @return the number of holds on the write lock by the current thread, * or zero if the write lock is not held by the current thread */ public int getWriteHoldCount() {//获取写锁的状态值 return sync.getWriteHoldCount();//调用相关方法 } /** * Queries the number of reentrant read holds on this lock by the * current thread. A reader thread has a hold on a lock for * each lock action that is not matched by an unlock action. * * @return the number of holds on the read lock by the current thread, * or zero if the read lock is not held by the current thread * @since 1.6 */ public int getReadHoldCount() {//获取读锁的计数器 return sync.getReadHoldCount();//调用相关方法 } /** * Returns a collection containing threads that may be waiting to * acquire the write lock. Because the actual set of threads may * change dynamically while constructing this result, the returned * collection is only a best-effort estimate. The elements of the * returned collection are in no particular order. This method is * designed to facilitate construction of subclasses that provide * more extensive lock monitoring facilities. * * @return the collection of threads */ protected Collection<Thread> getQueuedWriterThreads() {//获取队列里所有的非共享的等待线程 return sync.getExclusiveQueuedThreads();//调用AQS同步器里的方法 } /** * Returns a collection containing threads that may be waiting to * acquire the read lock. Because the actual set of threads may * change dynamically while constructing this result, the returned * collection is only a best-effort estimate. The elements of the * returned collection are in no particular order. This method is * designed to facilitate construction of subclasses that provide * more extensive lock monitoring facilities. * * @return the collection of threads */ protected Collection<Thread> getQueuedReaderThreads() {//获取队列里所有的共享的等待线程 return sync.getSharedQueuedThreads();//调用AQS同步器里的方法 } /** * Queries whether any threads are waiting to acquire the read or * write lock. Note that because cancellations may occur at any * time, a {@code true} return does not guarantee that any other * thread will ever acquire a lock. This method is designed * primarily for use in monitoring of the system state. * * @return {@code true} if there may be other threads waiting to * acquire the lock */ public final boolean hasQueuedThreads() {//判断队列里是否有等待的线程 return sync.hasQueuedThreads();//调用AQS同步器里的方法 } /** * Queries whether the given thread is waiting to acquire either * the read or write lock. Note that because cancellations may * occur at any time, a {@code true} return does not guarantee * that this thread will ever acquire a lock. This method is * designed primarily for use in monitoring of the system state. * * @param thread the thread * @return {@code true} if the given thread is queued waiting for this lock * @throws NullPointerException if the thread is null */ public final boolean hasQueuedThread(Thread thread) {//判断指定线程是否在等待队列里 return sync.isQueued(thread);//调用AQS同步器相关方法 } /** * Returns an estimate of the number of threads waiting to acquire * either the read or write lock. The value is only an estimate * because the number of threads may change dynamically while this * method traverses internal data structures. This method is * designed for use in monitoring of the system state, not for * synchronization control. * * @return the estimated number of threads waiting for this lock */ public final int getQueueLength() {//获取等待队列中线程大小 return sync.getQueueLength();//调用AQS同步器对应方法 } /** * Returns a collection containing threads that may be waiting to * acquire either the read or write lock. Because the actual set * of threads may change dynamically while constructing this * result, the returned collection is only a best-effort estimate. * The elements of the returned collection are in no particular * order. This method is designed to facilitate construction of * subclasses that provide more extensive monitoring facilities. * * @return the collection of threads */ protected Collection<Thread> getQueuedThreads() {//获取等待队列里所有等待的线程对象 return sync.getQueuedThreads();//调用AQS同步器对应方法 } /** * Queries whether any threads are waiting on the given condition * associated with the write lock. Note that because timeouts and * interrupts may occur at any time, a {@code true} return does * not guarantee that a future {@code signal} will awaken any * threads. This method is designed primarily for use in * monitoring of the system state. * * @param condition the condition * @return {@code true} if there are any waiting threads * @throws IllegalMonitorStateException if this lock is not held * @throws IllegalArgumentException if the given condition is * not associated with this lock * @throws NullPointerException if the condition is null */ public boolean hasWaiters(Condition condition) {//判断指定Condition队列里是否有condition节点对象 if (condition == null)//condition为null throw new NullPointerException();//抛异常 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))//传入的condition对象不是AQS同步器的ConditionObject对象 throw new IllegalArgumentException("not owner");//抛异常 return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);//调用AQS同步器里的方法 } /** * Returns an estimate of the number of threads waiting on the * given condition associated with the write lock. Note that because * timeouts and interrupts may occur at any time, the estimate * serves only as an upper bound on the actual number of waiters. * This method is designed for use in monitoring of the system * state, not for synchronization control. * * @param condition the condition * @return the estimated number of waiting threads * @throws IllegalMonitorStateException if this lock is not held * @throws IllegalArgumentException if the given condition is * not associated with this lock * @throws NullPointerException if the condition is null */ public int getWaitQueueLength(Condition condition) {//获取队里里指定Condition队列里等待节点的数量 if (condition == null)//condition为null throw new NullPointerException();//抛异常 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))//传入的condition对象不是AQS同步器的ConditionObject对象 throw new IllegalArgumentException("not owner");//抛异常 return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);//调用AQS同步器里的方法 } /** * Returns a collection containing those threads that may be * waiting on the given condition associated with the write lock. * Because the actual set of threads may change dynamically while * constructing this result, the returned collection is only a * best-effort estimate. The elements of the returned collection * are in no particular order. This method is designed to * facilitate construction of subclasses that provide more * extensive condition monitoring facilities. * * @param condition the condition * @return the collection of threads * @throws IllegalMonitorStateException if this lock is not held * @throws IllegalArgumentException if the given condition is * not associated with this lock * @throws NullPointerException if the condition is null */ protected Collection<Thread> getWaitingThreads(Condition condition) {//获取指定condition队列里等待的线程对象 if (condition == null)//condition为null throw new NullPointerException();//抛异常 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))//传入的condition对象不是AQS同步器的ConditionObject对象 throw new IllegalArgumentException("not owner");//抛异常 return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);//调用AQS同步器里的方法 } /** * Returns a string identifying this lock, as well as its lock state. * The state, in brackets, includes the String {@code "Write locks ="} * followed by the number of reentrantly held write locks, and the * String {@code "Read locks ="} followed by the number of held * read locks. * * @return a string identifying this lock, as well as its lock state */ public String toString() {//重写toString方法 int c = sync.getCount(); int w = Sync.exclusiveCount(c); int r = Sync.sharedCount(c); return super.toString() + "[Write locks = " + w + ", Read locks = " + r + "]"; } /** * Returns the thread id for the given thread. We must access * this directly rather than via method Thread.getId() because * getId() is not final, and has been known to be overridden in * ways that do not preserve unique mappings. */ static final long getThreadId(Thread thread) {//以保证原子性的方式获取线程的id 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;//获取线程Thread的class对象 TID_OFFSET = UNSAFE.objectFieldOffset (tk.getDeclaredField("tid"));//以反射的方式获取Thread的tid属性并保证原子性 } catch (Exception e) { throw new Error(e); } } }
ReentrantReadWriteLock源码解读,转载请注明出处,谢谢
最新推荐文章于 2022-09-07 03:55:21 发布