java中的读/写锁
2024-10-20 13:41:51
读写锁接口:ReadWriteLock,它的具体实现类为:ReentrantReadWriteLock
使用场景:
对于一个资源,读读能共存,读写不能共存,写写不能共存。
锁降级:从写锁变成读锁;
锁升级:从读锁变成写锁。
ReentrantReadWriteLock不支持锁升级,支持锁降级
ReadWriteLock rtLock = new ReentrantReadWriteLock();
rtLock.readLock().lock();
System.out.println("get readLock.");
rtLock.writeLock().lock();
System.out.println("blocking");
会死锁
ReadWriteLock rtLock = new ReentrantReadWriteLock();
rtLock.writeLock().lock();
System.out.println("writeLock"); rtLock.readLock().lock();
System.out.println("get read lock");
不会死锁
案例应用:
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class CacheDemo {
/**
* 缓存器,这里假设需要存储1000左右个缓存对象,按照默认的负载因子0.75,则容量=750,大概估计每一个节点链表长度为5个
* 那么数组长度大概为:150,又有雨设置map大小一般为2的指数,则最近的数字为:128
*/
private Map<String, Object> map = new HashMap<>(128);
private ReadWriteLock rwl = new ReentrantReadWriteLock();
public static void main(String[] args) { }
public Object get(String id){
Object value = null;
rwl.readLock().lock();//首先开启读锁,从缓存中去取
try{
value = map.get(id);
if(value == null){ //如果缓存中没有释放读锁,上写锁
rwl.readLock().unlock();
rwl.writeLock().lock();
try{
if(value == null){ //防止多写线程重复查询赋值
value = "redis-value"; //此时可以去数据库中查找,这里简单的模拟一下
}
rwl.readLock().lock(); //加读锁降级写锁,不明白的可以查看上面锁降级的原理与保持读取数据原子性的讲解
}finally{
rwl.writeLock().unlock(); //释放写锁
}
}
}finally{
rwl.readLock().unlock(); //最后释放读锁
}
return value;
}
}
如果不使用锁降级功能,如先释放写锁,然后获得读锁,在这个get过程中,可能会有其他线程竞争到写锁 或者是更新数据 则获得的数据是其他线程更新的数据,可能会造成数据的污染,即产生脏读的问题。
最新文章
- 用于灰度变换的一些实用的M函数
- NSXMLParser读取XML文件并将数据显示到TableView上
- 鸟哥的linux私房菜学习记录之账号管理与权限设定
- CSS控制div宽度最大宽度/高度和最小宽度/高度
- python实现雅虎拍卖后台自动回复卖家消息
- 为什么使用Redis
- JPA + SpringData 操作数据库 ---- 深入了解 SpringData
- 老男孩Python全栈开发(92天全)视频教程 自学笔记03
- 为什么要进行URL编码
- 树莓派3B(2)- 配置多个wifi,自动寻找可用网络
- Spring Boot 2.x (八):日志框架的使用
- Vue(二)简单入门
- 009_关闭linux的THP
- [LeetCode&;Python] Problem 118. Pascal&#39;s Triangle
- 《JavaScript高级教程》学习笔记一、变量和数据类型
- JDBC连接SQLServer出现的异常
- 大数据处理-Bitmap
- jboss 5.1 启动问题解决
- 简单的dp加贪心
- 使用gdb调试
热门文章
- appuim操作webview控件
- vue组件 $children,$refs,$parent的使用
- 初学HBase的几个问题
- jquery淡入淡出轮播图
- BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁(dp)
- atm-interface-shopping
- JZOJ 5184. 【NOIP2017提高组模拟6.29】Gift
- JZOJ 5456. 【NOIP2017提高A组冲刺11.6】奇怪的队列
- Python知识点入门笔记——基本控制流程
- python语言介绍