并发源码_ReentrantReadWriteLock源码分析
2023-04-04 09:21:42 0 举报
ReentrantReadWriteLock源码分析
作者其他创作
大纲/内容
重入最大次数小于65525
判断是否是第一个加读锁的线程r == 0
等于0
第一个获取读锁的线程
公平锁
不为0
不等于0说明有加锁的状态
获取当前线程Thread.currentThread()
判断当前同步状态state != 0
设置写锁为当前线程所有setExclusiveOwnerThread(current)
CAS成功
状态不能与0不能确定是写锁还是读锁,所以需要再根据写锁的重入次数在进行判断
判断重入数w==0
不是重入写写互斥
继续重入+1但是最大次数小于65525
不等于0
getExclusiveOwnerThread() != current
自旋
构建同步队列
返回失败-1
是重入
直接返回false
加锁失败
writerShouldBlock()当前线程是否被阻塞
读锁获取tryAcquireShared
区分公平锁和非公平锁
不等于0且线程是当前线程表示第一个获取读锁的线程重入
阻塞
获取state状态getState()
判断写锁的重入次数exclusiveCount(c) != 0
写锁获取tryAcquire
写读互斥
这里面重入最大次数小于65525
存在读锁或者写锁,状态就不为0
不是当前自己的线程
如果写锁已经被获取并且获取写锁的线程不是当前线程,当前线程获取读锁失败返回-1 判断锁降级
获取读锁的数量 int r = sharedCount(c)
非公平锁
读读共享写写互斥读写互斥写读互斥用int类型变量的state表示读锁数量和写锁数量。int类型变量是32位。其中高16位表示读锁数量;低16位表示写锁数量static final int SHARED_SHIFT = 16; // 此值为65536 static final int SHARED_UNIT = (1 << SHARED_SHIFT); //此值为65526-1=65525,表示16位数能表示的最大值。 static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;获取当前的state,当做参数c传入此方法,获取c的高16位的值static int sharedCount(int c) { return c >>> SHARED_SHIFT; }// 读锁加1的方法是state+SHARED_UNIT,表示在state的前16位上+1// 读锁减1的方法是state-SHARED_UNIT,表示在state的前16位上-1HoldCounter 计数器读锁的内在机制其实就是一个共享锁。一次共享锁的操作就相当于对HoldCounter 计数器的操作。获取共享锁,则该计数器 + 1,释放共享锁,该计数器 - 1。只有当线程获取共享锁后才能对共享锁进行释放、重入操作。通过 ThreadLocalHoldCounter 类,HoldCounter 与线程进行绑定。HoldCounter 是绑定线程的一个计数器,而 ThreadLocalHoldCounter 则是线程绑定的 ThreadLocalHoldCounter是用来记录读锁重入数的对象ThreadLocalHoldCounter是ThreadLocal变量,用来存放不是第一个获取读锁的线程的其他线程的读锁重入数对象
不阻塞
HoldCounter++
c==0 写锁未被任何线程获取
说明是有读锁
readerShouldBlock()
加读锁
CAS失败
获取写锁的重入数getState()exclusiveCount(c)
设置第一个获取读锁的线程 firstReader = currentfirstReaderHoldCount = 1
不等于0且线程是当前线程 非第一个获取读锁的线程
在进行是否是是当前线程重入
firstReaderHoldCount++;
0 条评论
下一页