您当前的位置: 首页 > 

顧棟

暂无认证

  • 0浏览

    0关注

    227博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【JUC系列】LOCK框架系列之七 核心锁类之ReentrantReadWriteLock

顧棟 发布时间:2022-04-30 06:00:00 ,浏览量:0

ReentrantReadWriteLock

文章目录
  • ReentrantReadWriteLock
    • 什么是读写锁
    • 核心实现思想
      • 计算演示
    • 读写锁的特性
      • 读写锁的组成
        • 类图
        • 构造函数
        • 内部类Sync
          • 构造方法
          • 主要成员
          • 主要方法
          • Sync完整源码
        • NonFairSync
        • FairSync
    • 写锁的获取与释放
    • 读锁的获取与释放
    • 锁的降级

什么是读写锁

读写锁支持支持多个线程同时读,但是当一个写线程访问的时候会阻塞其他所有写和读的线程。

读写锁同时拥有写锁和读锁,通过分离读写锁提高程序的执行效率,在读多写少的场景中,并发性能比单一的排他锁有明显提升。

核心实现思想

读写锁内部重新定义了AQS中的同步状态变量的state。从低16位(0-15)用来记录写锁,用高16位(16-31)记录读锁。写锁的16位可以用来表示写锁被重入的次数。读锁的16位既可以表示一个读线程的重入次数,也可以表示多少个线程获得了读锁。state==0表示既无写锁又无读锁。

        // 共享式的位移量 读锁的使用的位数
        static final int SHARED_SHIFT   = 16;
        // 将1左移16位,结果作为,高位读锁(共享)的计算基本单位 65536
        static final int SHARED_UNIT    = (1 16的值为1

exclusiveCount(5),通过以下计算得知:此时的读锁个数是5个。

-------------------  -------------------
0000 0000 0000 0000  0000 0000 0000 0101   // 5的二进制
0000 0000 0000 0000  1111 1111 1111 1111   // EXCLUSIVE_MASK 65535
0000 0000 0000 0000  0000 0000 0000 0101   // 5 & 65535 = 5
读写锁的特性 特性说明公平性支持公平锁与非公平锁,默认非公平模式,吞吐量还是非公平高于公平重入性该锁支持重进入,以读写线程为例:读线程在获取了读锁之后,能够再次获取读锁。而写线程在获取写锁之后,能够再次获取写锁,同时可以获取读锁锁降级遵循读写锁、获取读锁在释放写锁的次序,写锁能够降级为读锁 读写锁的组成 类图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传站可能有防盗链机制,建议将图片保存下来直接上传(img-BfltwiOH-1650612392958)(images\image-20220411111402223.png)]

构造函数

在构造函数中会去构造ReadLock和WriteLock,WriteLock和ReadLock使用的是同一个AQS对象(Sync),这样就具备AQS的特性且互斥。

    /**
    * 无参构造函数 默认采用非公平策略
    */
	public ReentrantReadWriteLock() {
        this(false);
    }

    /**
    * 含参构造函数 false非公平策略 true公平策略
    */
    public ReentrantReadWriteLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
        readerLock = new ReadLock(this);
        writerLock = new WriteLock(this);
    }

	// 读锁
    public static class ReadLock implements Lock, java.io.Serializable {
      
        private final Sync sync;

        protected ReadLock(ReentrantReadWriteLock lock) {
            sync = lock.sync;
        }
    }

	// 写锁
	public static class WriteLock implements Lock, java.io.Serializable {
      
        private final Sync sync;

        protected WriteLock(ReentrantReadWriteLock lock) {
            sync = lock.sync;
        }
    }
内部类Sync 构造方法

主要是对读锁计数器的初始化。

        Sync() {
            // 初始化本地线程计数器
            readHolds = new ThreadLocalHoldCounter();
            setState(getState()); // ensures visibility of readHolds
        }

		// 利用ThreadLocal来存储本地线程计数器
        static final class ThreadLocalHoldCounter
            extends ThreadLocal {
            public HoldCounter initialValue() {
                return new HoldCounter();
            }
        }
		// 本地线程计数器 count用来存储数量 tid代表线程的ID值
        static final class HoldCounter {
            int count = 0;
            // Use id, not reference, to avoid garbage retention
            final long tid = getThreadId(Thread.currentThread());
        }
主要成员
        // 共享式的位移量 读锁的使用的位数
        static final int SHARED_SHIFT   = 16;
        // 将1左移16位,结果作为,高位读锁(共享)的计算基本单位
        static final int SHARED_UNIT    = (1             
关注
打赏
1663402667
查看更多评论
0.0428s