要点:

  • 读写状态设计
  • 写锁的获取和释放
  • 读锁的获取和释放

    读写状态设计

  • 关键点:在同步变量上 维护多个读线程 和 一个写线程
  • 实现策略:状态的按位划分
    • 写状态记录在整形的低16位
    • 读状态记录在整形的高16位
    • 写状态更新:S+1
    • 读状态更新:S+(1<<16)
    • 判断是否读状态:S不等于0,且S&0x0000FFFF 等于0

image.png

写锁的获取和释放

  1. tryAcquire(int arg)方法
    1. c&0x0000FFFF -> 校验是否有读锁
    2. 有读锁且不是这个线程占有的读锁,就返回 false
    3. 写锁的重入次数最多 2^16 - 1
  2. 释放和可重入锁释放一致

    读锁的获取和释放

    读锁是可重入、共享锁。当没有写线程访问时,读锁总会被成功的获取。JDK6新增获取当前线程获取读锁的次数(getReadHoldCount()).

  3. tryAcquireShared(int unused)

    1. 判断是否超过最大读锁加锁次数
    2. 判断是否有写锁和是否写锁属于自己
    3. 读锁++

      锁降级

      锁降级是线程先获取写锁->再获取读锁->释放写锁。