Java并发-17.读写锁

  • 读写锁维护一对锁,读锁和写锁
  • 分离读锁和写锁,并发性比排它锁有很大提升
  • ReadWriteLock仅定义读锁和写锁的两个方法——readLock()和writeLock()
  • 实现类ReentrantReadWriteLock提供了以下方法:

方法

描述

int getReadLockCount()

返回当前读锁被获取的次数。该次数不等于获取读锁的线程数,比如:仅一个线程,它连续获取(重进入)了n次读锁,那么占据读锁的线程数是1,但该方法返回n

int getReadHoldCount()

返回当前线程获取读锁的次数。该方法在Java 6 中加入到ReentrantReadWriteLock中,使用ThreadLocal保存当前线程获取的次数,这也使得Java 6 的实现变得更加复杂

boolean isWriteLocked()

判断写锁是否被获取

int getWriteHoldCount()

返回当前写锁被获取的次数

  • 读写锁状态的设计:
    • 通过运用“按位切割使用”同步状态(一个整形变量),来维护多个读线程和一个写线程。(高16位读,底16位写)。
    • 锁状态S不等于0时,当写状态(S&0x0000FFFF)等于0时,则读状态(S>>>16)大于0,读锁已被获取。
  • 写锁的获取和释放:
    • 写锁支持重进入:
      • 当前线程获取了写锁,增加写状态
      • 当前线程获取写锁时,读锁已经被获取或者线程不是获取写锁的进程,当前线程进入等待状态
  • 读锁的获取和释放
    • 读锁可以被多个线程同时获取,没有其他线程访问或者写状态为0,读锁总是可以获取成功,并增加读状态
    • 如果写锁被其他线程获取了。读锁进入等待状态
  • 锁降级
    • 写锁降级成读锁:把当前持有的写锁,再获取到读锁,随后释放(之前拥有的)写锁
    • 锁降级作用:如果线程获取读锁而是直接释放写锁,假设某线程获取了写锁并修改了数据,当前线程无法获取数据更新了。
    • ReentrantReadWriteLock不支持锁升级,也是因为如果读锁被多个线程获取,任意线程获取了写锁并更新数据,其更新对其他获取到读锁的线程是不可见的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券