多线程之读写锁ReadWriteLock的深度理解及用读写锁实现缓存《十》

本文详细探讨了Java中ReadWriteBarrierLock的引入原因、特有方法,重点介绍了写锁、读锁的概念,阐述了锁降级的重要性——确保数据可见性,并通过一个实例展示了如何利用锁降级实现缓存,最后进行了结果分析。
摘要由CSDN通过智能技术生成
读写锁
1. 为什么要引入读写锁?
1. 重入锁是一个时刻只能一个线程访问,读写锁同一个时刻允许多个线程访问
2. 但是在写线程访问时,所有的读线程和其他写线程均被阻塞
3. 读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,
   通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升  
2. 读写锁特有的方法
1. readLock() 获取读锁
2. writeLock() 获取写锁
3. int getReadLockCount() 返回当前读锁被读的次数,而不等于获取读锁的线程数
   比如一个线程读了N次,返回的就是N
4. int getReadHoldCount() 返回当前线程获取读锁的次数
5. boolean is WriteLocked 返回当前写锁是否被获取
6. int getWriteHoldCount   返回当前写锁被读取的次数
3. 写锁
1. 写锁是一个支持重进入的排他锁,和重入锁一样,只有状态为0才释放当先线程写锁
2. 但是除了重入条件,写锁增加了一个读锁是否存在的判断?
如果存在读锁,则写锁不能被获取,原因是:
2.1 读写锁要确保写锁的操作要对读锁 可见,如果允许读锁在已经被获取的情况下对写锁获取,那么
正在允许的其它读线程就不能感知到当前写线程的操作
2.2 因此只有等待其它读线程都释放了锁,写操作才能被获取
2.3 而且写锁一旦被获取,其它读线程的后续均被阻塞
4. 读锁
1. 读锁是一个支持重进入的共享锁,能被多个线程同时获取
2. 如果其他线程已经获取了写锁,则当前线程获取读锁失败,进入等待状态
3. 如果当前线程获取了写锁或者写锁未被获取,则当前线程(线程安全,依靠CAS保证)增加读状态,成功获取读锁。
4. 读锁每次释放均减少读状态,减少的值是1<<16
5. 锁降级
锁降级是指:写锁降级成为读锁
1. 一个拥有写锁的线程,释放写锁,再获取读锁,这种分段完成的过程不能称之为锁降级
2. 锁降级是指持住当前线程拥有的写锁,再获取读锁,随后释放先前拥有写锁的过程
// 锁降级的示例:

public void processData() {
        readLock.lock();
        if (!update) {
			// 必须先释放读锁
            readLock.unlock();
			// 锁降级从写锁获取到开始
            writeLock.lock();
            try {
                if (!update) {
					// 准备数据的流程(略)
                    update = true;
                }
                readLock.lock();
            } finally {
                writeLock.unlock();
            }
		// 锁降级完成,写锁降级为读锁
        }
        try {
			// 使用数据的流程(略)
        } finally {
            readLock.unlock();
        }
    }
6.为什么需要锁降级?

目的:保证数据的可见性

试想:
1. 如果当写前线程A不获取读锁,而是直接释放写锁
2. 另一个线程B获取写锁,修改数据,那么线程A是无法感知数据被修改了的
7. 读写锁支持锁升级吗?
不支持,为什么?
目的: 保证数据可见性
试想: 
     如果读锁已经被多个数据获取了,其中任意线程成功获取了写锁,并修改了数据
     则其更新对其它获取到的读锁都是不可见的
8. 用锁降级实现一个缓存
package duoxianc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值