读写锁
读写锁ReetrantReadWriteLock实现分析:读写状态的设计、写锁的获取与释放、读锁的获取与释放以及锁降级。
1)读写状态的设计
读写锁将state切分成了两部分,高16位表示读,低16位表示写。
假设当前同步状态值为S,写状态等于S&0X0000FFFF(将高16位全部抹去),读状态等于S>>>16(无符号补0右移16位)。当写状态增加1时,等于S+1,当读状态增加1时,等于S+(1<<16),也就是S+0X00010000。
2)写锁的获取与释放
写锁的获取:
tryAcquire(int acquires),该方法除了重入条件(当前线程为获取了写锁的线程)之外,增加了一个读锁是否存在的判断。如果存在读锁,则写锁不能被获取。
写锁的释放:
写锁的释放与ReentrantLock的释放过程基本类似,每次释放均减少写状态,当写状态为0时表示写锁已被释放,从而等待的读写线程能够继续访问读写锁,同时前次写线程的修改对后续写线程可见。
3)读锁的获取与释放
tryAcquireShared(int acquires),如果当前线程获取了写锁或者写锁未被获取,则当前线程(线程安全,依靠CAS保证)增加读状态,成果获取读锁。
4)锁降级
锁降级是指当前拥有写锁,再获取到读锁,随后释放写锁的过程。(主要是为了保证数据的可见性。如果当前 线程不获取读锁而是直接释放写锁,假设此刻T线程获取了写锁并修改了数据,那么当前线程无法感知T线程的数据更新。{待定})