ReentrantReadWriteLock类源代码分析
来源:互联网 发布:java中point的用法 编辑:程序博客网 时间:2024/06/18 09:16
参考网址:
http://blog.csdn.net/qq_19431333/article/details/70568478
011
& 001
——————
001
static final int SHARED_SHIFT = 16; static final int SHARED_UNIT = (1 << SHARED_SHIFT)=65536; static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1 = 65535; static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1 = 65535; //当c>65535时不为0, 0<=c<65535时为0, c<0时为65535 static int sharedCount(int c) { return c >>> SHARED_SHIFT; } //当c>65535时不为c-65536*i, 0<=c<65535时为c, c<0时c+65536*i static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
m”<<”n 有符号左移: 不管m是正数还是负数,m向左移n位后,在低位补n个0.
m>>n 有符号右移: 如果m是正数,m向右移n位,在高位补n个0.如果m是负数,m向右移n位,在高位补n个1.
m>>>n 无符号右移(java不存在无符号左移符号): 不管m是正数还是负数,m向右移n位,都在高位补n个0.
ReentrantReadWriteLock类
int sharedCount(int c) 获取读线程数,包括重入数
int exclusiveCount(int c) 获取写线程数(包括重入数)
boolean tryRelease(int releases)
释放锁后状态为0返回true,否则返回false
1、非公平锁(吞吐率比公平锁高)
第一个尝试获取锁的线程都可以获得锁资源
当写锁时,该线程的读锁和写锁可以获得锁,其他线程的写锁和读锁都得不到锁资源,进入队列等待。
读锁时,所有读锁可以得到锁,所有写锁进入队列等待。
2、公平锁
线程将会以队列的顺序获取锁。当当前线程释放锁后,等待时间最长的写锁线程就会被分配写锁;或者有一组读线程组等待时间比写线程长,那么这组读线程组将会被分配读锁。
3、支持锁重入,即同一个thread对调用多次lock.lock()方法,且获得锁资源。
4、允许写锁降低为读锁 ,即同一个thread当调用 writeLock.lock()获得锁资源后,readLock.lock()也可以获得锁资源,writeLock.unlock()是否所后降级为读锁.
5、在读锁和写锁的获取过程中支持中断,方法为WriteLock和ReadLock中的 lockInterruptibly()、tryLock(long timeout, TimeUnit unit)会抛出InterruptedException
6、写锁提供Condition实现 ,读锁不支持Condition实现。
public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable { private static final long serialVersionUID = -6992448646407690164L; private final ReentrantReadWriteLock.ReadLock readerLock; private final ReentrantReadWriteLock.WriteLock writerLock; 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; } /** * 继承AbstractQueuedSynchronizer */ abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 6317671515068378041L; 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; /** 获取读锁线程数,高16位代表读锁的个数 ,即是 SHARED_UNIT的倍数*/ static int sharedCount(int c) { return c >>> SHARED_SHIFT; } /** 获取写锁线程数 ,低16位代表写锁的状态*/ static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; } /** * 记录当前读线程的锁重入数,相当于计数器 */ static final class HoldCounter { int count = 0; // 当前线程的id,不直接使用Thread.currentThread(),防止对线程的依赖,有利于GC回收 final long tid = getThreadId(Thread.currentThread()); } //线程安全变量计数器 static final class ThreadLocalHoldCounter extends ThreadLocal<HoldCounter> { public HoldCounter initialValue() { return new HoldCounter(); } } /** * 线程安全变量记录当前线程的占用锁重入数 * 当读线程持有数为0时移除 * 与使用cachedHoldCounter相比,从readHolds读取数据资源消耗大很多,故因先判断cachedHoldCounter是不是当前线程计数器,不是则从readHolds读取 */ 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 } /** * 获取读锁时是否应该阻塞,true:进入队列排队 false:可以获得锁资源 */ abstract boolean readerShouldBlock(); /** * 获取写锁时是否应该阻塞,true:进入队列排队 false:可以获得锁资源 */ 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) //如果没有写锁了,那么将AQS的线程置为null setExclusiveOwnerThread(null); setState(nextc); return free; } /** * 获取写锁 */ protected final boolean tryAcquire(int acquires) { /* * 1. 如果当前有写锁或者读锁。如果只有读锁,返回false,因为这时如果可以写,那么读线程得到的数据就有可能错误;如果有写锁,但是线程不同,即不符合写锁重入规则,返回false 2. 如果写锁的数量将会超过最大值65535,抛出异常;否则,写锁重入 3. 如果没有读锁或写锁的话,如果需要阻塞或者CAS失败,返回false;否则将当前线程置为获得写锁的线程 */ Thread current = Thread.currentThread(); int c = getState(); //获取写锁 int w = exclusiveCount(c); //有写锁或者读锁 if (c != 0) { // 有读锁或者其他写锁返回false if (w == 0 || current != getExclusiveOwnerThread()) return false; //如果写锁的个数超过了最大值,抛出异常 if (w + exclusiveCount(acquires) > MAX_COUNT) throw new Error("Maximum lock count exceeded"); // 写锁重入,返回true setState(c + acquires); return true; } //当前没有写锁或者读锁,如果写线程应该阻塞或者CAS失败,返回false //公平锁需要判断当前线程是否为队列头节点,是则立即CAS更新队列状态 //非公平锁立即CAS更新队列状态 if (writerShouldBlock() || !compareAndSetState(c, c + acquires)) return false; //否则将当前线程置为获得写锁的线程,返回true setExclusiveOwnerThread(current); return true; } /** * 尝试释放读锁 */ protected final boolean tryReleaseShared(int unused) { Thread current = Thread.currentThread(); //第一个获得读锁线程未当前线程 if (firstReader == current) { // 当前读锁重入数为1则当前线程释放锁资源 if (firstReaderHoldCount == 1) firstReader = null; else firstReaderHoldCount--; } else { //获取最后一个获取读锁的线程计数器 HoldCounter rh = cachedHoldCounter; //最后一个获取读锁计数器为null 或者 读锁线程id不等于当前线程id 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(); //释放一把读锁,因为读锁采用高16位, nextc为 SHARED_UNIT的整数倍 int nextc = c - SHARED_UNIT; if (compareAndSetState(c, nextc)) //读锁全部释放返回true return nextc == 0; } } private IllegalMonitorStateException unmatchedUnlockException() { return new IllegalMonitorStateException( "attempt to unlock read lock, not locked by current thread"); } /** * 尝试获取读锁(lock方法流程会用到该方法) */ protected final int tryAcquireShared(int unused) { Thread current = Thread.currentThread(); int c = getState(); //有写锁且不为当前线程返回-1 if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return -1; //获取读锁线程数 int r = sharedCount(c); //读线程不应该阻塞并且读锁的个数小于最大值65535,成功更新状态值 //非公平锁通过判断锁是否被写线程占用,被占用则不允许获取读锁 //公平锁 通过判断当前线程未队列头结点 if (!readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) { //没有其他读线程,设置当前线程为第一个读线程,firstReaderHoldCount=1 if (r == 0) { firstReader = current; firstReaderHoldCount = 1; } else if (firstReader == current) { //锁重入 firstReaderHoldCount++; } else { //获取最后一个获取读锁的线程计数器 HoldCounter rh = cachedHoldCounter; //最后一个获取读锁计数器为null 或者 读锁线程id不等于当前线程id if (rh == null || rh.tid != getThreadId(current)) ////从当前线程安全变量中读取,消耗较从缓存中读取大很多,并设置最后一个获取读锁为当前线程计数器 cachedHoldCounter = rh = readHolds.get(); //最后一个获取读锁计数器值为0 else if (rh.count == 0) //设置线程安全变量值 readHolds.set(rh); //计数器加1 rh.count++; } return 1; } //不满足获取读锁条件则循环,直到获得读锁成功或抛出异常 return fullTryAcquireShared(current); } /** * 循环获取读锁,直到获得读锁成功或抛出异常,逻辑类似tryAcquireShared方法 */ final int fullTryAcquireShared(Thread current) { HoldCounter rh = null; //循环 for (;;) { int c = getState(); //有写锁且不为当前线程返回-1 if (exclusiveCount(c) != 0) { if (getExclusiveOwnerThread() != current) return -1; } //不允许获得读锁(比如公平锁必须当前线程未头节点) else if (readerShouldBlock()) { // Make sure we're not acquiring read lock reentrantly if (firstReader == current) { // assert firstReaderHoldCount > 0; } else { //其他线程持有锁 if (rh == null) { rh = cachedHoldCounter; //最后一个获取读锁计数器为null 或者 读锁线程id不等于当前线程id if (rh == null || rh.tid != getThreadId(current)) { rh = readHolds.get(); //计数器值为0移除 if (rh.count == 0) readHolds.remove(); } } if (rh.count == 0) return -1; } } //如果读锁达到了最大值,抛出异常 if (sharedCount(c) == MAX_COUNT) throw new Error("Maximum lock count exceeded"); //和tryAcquireShared方法逻辑一致 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; } } } /** * 除了writerShouldBlock判断,其他与tryAcquire一致 */ 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"); } if (!compareAndSetState(c, c + 1)) return false; setExclusiveOwnerThread(current); return true; } /** * 除了readerShouldBlock判断,其他与tryAcquireShared一致 * 非公平锁可以直接调用这个 */ 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; } final int getCount() { return getState(); } } /** * 非公平锁 */ static final class NonfairSync extends Sync { private static final long serialVersionUID = -8159625535654395037L; final boolean writerShouldBlock() { return false; // writers can always barge } final boolean readerShouldBlock() { //该方法在当前线程是写锁占用的线程时,返回true;否则返回false return apparentlyFirstQueuedIsExclusive(); } } /** * 公平锁 */ static final class FairSync extends Sync { private static final long serialVersionUID = -2274990926593161451L; //当前线程为队列头结点 final boolean writerShouldBlock() { return hasQueuedPredecessors(); } 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); } /** /** * 读锁没有占用锁资源 立马占用锁资源并返回 * 否则进入队列等待获取锁资源,获得锁资源立马返回,否则直到其他线程调用该线程的Interrupt()方法则抛出异常 */ 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); } 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(); } /** * thread是否在队列中等待获取资源 */ public final boolean hasQueuedThread(Thread thread) { return sync.isQueued(thread); } /** * 返回队列长度 */ public final int getQueueLength() { return sync.getQueueLength(); } /** * 返回队列中所有读线程和写线程的集合 */ protected Collection<Thread> getQueuedThreads() { return sync.getQueuedThreads(); } /** * condition队列中是否有等待被唤醒的写线程 */ 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); } /** *返回condition队列中所有等待被唤醒(waitState=-2)写线程的个数 */ 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); } /** * 返回condition队列中所有等待被唤醒(waitState=-2)写线程的集合 */ 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 + "]"; } /** * 获取线程变量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 = sun.misc.Unsafe.getUnsafe(); Class<?> tk = Thread.class; TID_OFFSET = UNSAFE.objectFieldOffset (tk.getDeclaredField("tid")); } catch (Exception e) { throw new Error(e); } }}
- ReentrantReadWriteLock类源代码分析
- ReentrantReadWriteLock分析
- 类 ReentrantReadWriteLock
- ReentrantReadWriteLock源码分析
- ReentrantReadWriteLock原理分析
- JUC - ReentrantReadWriteLock 源码分析
- ReentrantReadWriteLock深入分析
- ReentrantReadWriteLock深入分析
- ReentrantReadWriteLock深入分析
- ReentrantReadWriteLock可重入读写锁分析
- Java并发-ReentrantReadWriteLock源码分析
- ReentrantReadWriteLock源码分析(JDK 1.7)
- ReentrantReadWriteLock与ReentrantLock对比分析
- Java多线程 ReentrantReadWriteLock深入分析
- Java 并发 ---ReentrantReadWriteLock源码分析
- 使用ReentrantReadWriteLock类
- 使用ReentrantReadWriteLock类
- ReentrantReadWriteLock
- 在java中调用C#编写的dll
- Oracle高水位线
- c语言之单链表
- python中需要注意的一些地方
- ubuntu安装/更新cudnn版本遇到的问题
- ReentrantReadWriteLock类源代码分析
- Java抽象类和接口
- Problem B. Black and White Gym-100801B] 想象力
- Python初入门(一)(Head First Python 第一章 初识Python)
- Linux 管理网络
- Linux常用命令
- 今天是上班的第三天,以后的路还很长,记录一下个人的成长,本人屌丝程序猿一个
- 杭电1008坐电梯
- SQL经典题目