当前位置: 首页 > 后端技术 > Java

Java并发——通过ReentrantReadWriteLock理解AQS的独占模式和共享模式

时间:2023-04-01 18:54:02 Java

大家好,我是奇喵小屋,一个分享技术和生活的博主。以下是我的主页。每个主页都更新了高质量的博客。创建起来并不容易。请关注掘金主页。将来会发布更多的MySQL。Redis、并发、JVM、分布式等面试热点知识,以及Java学习路线、面试重点、职业规划、面经等相关博文转载请注明出处!1.类图结构ReadWriteLock中有一个Sync对象。ReadLock和WriteLock共享Sync对象。读锁和写锁底层是同一个锁。ReentrantReadWriteLock有一个读锁(ReadLock)和一个写锁(WriteLock)。是共享模式,写锁是独占模式。通过分离读写锁,提高了并发性。当读锁正在被使用时,其他线程可以直接获取读锁,不会阻塞。当读锁正在被使用时,如果其他线程试图获取写锁,将阻塞正在使用的写锁,其他线程试图获取读锁或写锁,将阻塞2.该特性支持公平锁和非公平锁锁,不同的是readerShouldBlock()和writerShouldBlock()的实现不同可重入:获取读锁后,可以再次获取读锁(但不能再次获取写锁。获取读锁后,如果再次获取写锁,线程将一直阻塞)。获取写锁后,可以再次获取写锁,也可以获取读锁降级:线程获取写锁后,获取读锁,然后先释放写锁——降级为读锁3.method方法说明intgetReadLockCount()获取读锁获取次数(同步状态state通过位运算获取)intgetWriteHoldCount()返回当前线程获取写锁的次数(exclusiveOwnerThread指向的线程是获取写锁的线程,通过位操作获取状态)intgetReadHoldCount()返回当前线程获取读锁的次数,Sync内部有一个ThreadLocalHoldCount(继承自ThreadLocal)保存次数oftimeseachthreadacquiresareadlock4.详细分析4.1读写状态的设计AQS通过同步状态state表示锁(0—锁可用,非0—锁不可用,可重用)每次重新锁-entered,state+1)但是在ReentrantReadWriteLock中,ReadLock和WriteLock共享一个state,所以不是这么简单的机制。32位状态处于可重入状态entrantReadWriteLock分为两部分(16+16)获取读锁,高16位+1(读锁状态——状态>>16,读状态不为0——已获取读锁)获取写锁,低16位+1(写锁状态-state&&0x0000FFFF,写状态不为0-已获取写锁)4.2写锁的获取与释放4.3读锁的获取与释放