前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java并发——ReentrantReadWriteLock如何同时实现AQS的独占模式和共享模式

Java并发——ReentrantReadWriteLock如何同时实现AQS的独占模式和共享模式

原创
作者头像
淇妙小屋
发布2022-04-02 17:04:36
3840
发布2022-04-02 17:04:36
举报
文章被收录于专栏:面试题详解面试题详解

大家好,这里是淇妙小屋,一个分享技术,分享生活的博主 以下是我的主页,各个主页同步更新优质博客,创作不易, 后续会发布更多MySQL,Redis,并发,JVM,分布式等面试热点知识,以及Java学习路线,面试重点,职业规划,面经等相关博客 转载请标明出处!

1. 类图结构

  • ReadWriteLock中有一个Sync对象,ReadLock与WriteLock共用Sync对象,读锁与写锁底层公用的是同一把锁
  • ReentrantReadWriteLock中有一个 读锁(ReadLock)与一个 写锁(WriteLock) 读锁共享模式写锁独占模式,通过分离读写锁,提高并发性
  • 读锁正在被使用时,其他线程可以直接获得读锁,不阻塞 读锁正在被使用时,如果其他线程尝试取得写锁,会阻塞 写锁正在被使用时,其他线程尝试获取读锁or写锁,都会阻塞

2. 特性

  1. 支持公平锁与非公平锁,区别在于 readerShouldBlock()writerShouldBlock()的实现不同
  2. 可重入:拿到读锁后,可以再次获取读锁(但是不能再次获取写锁,拿到读锁后如果再次获取写锁,线程会一直阻塞) 拿到写锁后,可以再次获取写锁,也可以再次获取读锁
  3. 锁降级:线程拿到写锁后,在获取读锁,然后先释放掉写锁——降级为读锁

3. 方法

方法

描述

int getReadLockCount()

获取读锁被获取的次数(同步状态state进行位运算得到)

int getWriteHoldCount()

返回当前线程获取写锁的次数(exclusiveOwnerThread指向的线程是获得写锁的线程,state进行位运算得到)

int getReadHoldCount()

返回当前线程获取读锁的次数,Sync内部有个ThreadLocalHoldCount(继承自ThreadLocal)保存有每个线程获取读锁的次数

4. 详细分析

4.1 读写状态设计

AQS通过 同步状态state来表示锁(0—锁可用,非0—锁不可用,可重入锁每重入一次state+1)

但在ReentrantReadWriteLock中ReadLock与WriteLock共用一个state,所以就不是这样简单的机制了

32位的state在ReentrantReadWriteLock中被划分为了两部分(16+16)

获得读锁,高16位+1(读锁状态——state>>16,读状态不为0——读锁已被获取)

获得写锁,低16位+1(写锁状态——state&&0x0000FFFF,写状态不为0——写锁已被获取)

4.2 写锁的获取与释放

4.3 读锁的获取与释放

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 类图结构
  • 2. 特性
  • 3. 方法
  • 4. 详细分析
    • 4.1 读写状态设计
      • 4.2 写锁的获取与释放
        • 4.3 读锁的获取与释放
        相关产品与服务
        云数据库 MySQL
        腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档