StampedLock是为了优化可重入读写锁性能的一个锁实现工具,jdk8开始引入
相比于普通的ReentranReadWriteLock主要多了一种乐观读的功能
在API上增加了stamp的入参和返回值
不支持重入
我看了上面的介绍仍然对StampedLock一头雾水,下面我们来揭开StampedLock神秘的面纱
1、对于悲观读和悲观写的方法与ReentranReadWriteLock读写锁效果一样
下面是StampedLock的悲观读、写锁的实现
测试一下效果:
输出结果:
数据写入完成
5064
readLock==0
写被读锁阻塞了5秒
2、对于乐观读(如果没有进入写模式)可以减少一次读锁的性能消耗,并且不会阻塞写入的操作(乐观读遇到写后转化为悲观,相当于滞后一步)
我们添加了一个乐观读的方法,这个方法仍然模拟读取延迟5秒,乐观读实现需要参考下面的编程模式(获取乐观锁、校验是否进入写模式)
测试一下效果:
输出结果:
数据写入完成
553
(中间等了大概5秒)
optimisticRead==1
写没有被被读锁阻塞,乐观读最终走了悲观读读取了最新值
针对以上代码我分别对乐观读锁和悲观读锁测试了5次,每次10000并发并且每次回sleep10ms,测试结果如下
乐观(ms)95 91 102 98 92
悲观(ms)265 253 293 265 287
乐观读锁整体性能大概是悲观读锁3倍
可以看到相比直接用悲观读锁,乐观读锁可以:
1、进入悲观读锁前先看下有没有进入写模式(说白了就是有没有已经获取了悲观写锁)
2、如果其他线程已经获取了悲观写锁,那么就只能老老实实的获取悲观读锁(这种情况相当于退化成了读写锁)
3、如果其他线程没有获取悲观写锁,那么就不用获取悲观读锁了,减少了一次获取悲观读锁的消耗和避免了因为读锁导致写锁阻塞的问题,直接返回读的数据即可(必须再tryOptimisticRead和validate之间获取好数据,否则数据可能会不一致了,试想如果过了validate再获取数据,这时数据可能被修改并且读操作也没有任何保护措施)
Original: https://www.cnblogs.com/zxporz/p/11642176.html
Author: 乂墨EMO
Title: StampedLock的理解和使用
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/583576/
转载文章受原作者版权保护。转载请注明原作者出处!