公众号merlinsea
特性:写写互斥,读写互斥,读读共享
锁降级:写线程在获取写锁以后,完成写操作以后可以获取读锁同时释放写锁,即实现了锁降级。
读写锁支持锁降级 为什么不支持锁升级?
答:锁降级是持有写锁的线程,可以进一步持有读锁,因为写锁只能有一个线程持有,因此锁降级不会造成数据的不一致性。锁升级是持有读锁的线程可以进一步持有写锁,因为在读写锁中,读锁可以被多个线程同时持有,如果允许锁升级,那么这些持有读锁的线程都可以申请写锁,这会导致多个线程同时修改共享变量,会造成数据不一致性,因此不支持锁升级。
根据上图的代码来解释ReentrantReadWriteLock如何用一个int state变量同时表示读锁和写锁的状态:
java中一个int型的整数是32位,其中用低16位表示写锁的状态,高16位表示读锁的状态 读锁每次重入都加上65536 0000000000000000 000000000000000 + 0000000000000001 000000000000000 -------------------------------------- 0000000000000001 000000000000000 判断有当前有多少线程持有读锁,status>>16 0000000000000001 000000000000000 >>16 ---------------------------------------- 0000000000000000 000000000000001 写锁每次重入加上1 0000000000000000 000000000000000 + 0000000000000000 000000000000001 -------------------------------------- 0000000000000000 000000000000001 判断有当前线程重入了多少次写锁,status & 65535 0000000000000001 0000000000000001 & 0000000000000000 1111111111111111 ---------------------------------------- 0000000000000000 0000000000000001
读锁加锁的核心代码
读锁解锁的核心代码注意点:
1、可以有很多不同的线程持有读锁,故这些持有读锁的线程可以串成一个链表连接。
2、每个持有读锁的线程内部会记录当前线程重入了多少次读锁 。
3、每次一个线程释放读锁的时候都要读锁的count--,当某个线程持有读锁次数为0时可以从链表中移除该线程。
写锁加锁核心代码
写锁解锁的核心代码