并发情况下ReentrantLock死锁
来源:互联网 发布:淘宝客cms优惠券系统 编辑:程序博客网 时间:2024/06/15 06:03
业务背景:
系统启动时需要向DRM服务器注册资源,同一个资源只能注册一次,不能重复注册。现在有两个资源需要注册,第一个资源为Profile阀门控制,第二个资源为模型阀门控制。
存在缺陷的代码:
public class CommonConfig { /** 非公平锁 */ private static ReentrantLock lock = new ReentrantLock(false); /** profile相关阀门控制*/ private ProfileConfigResource profileConfigResource; /** 模型相关阀门控制*/ private ModelConfigResource modelConfigResource; public ProfileConfigResource getProfileResource() { if (profileConfigResource == null) { lock.lock(); if (profileConfigResource != null) { return profileConfigResource; } ProfileConfigResource profileConfig = new ProfileConfigResource(); DRMClient.getInstance().register(profileConfig); profileConfigResource = profileConfig; lock.unlock(); } return profileConfigResource; } public ModelConfigResource getModelResource() { if (modelConfigResource == null) { lock.lock(); if (modelConfigResource != null) { return modelConfigResource; } ModelConfigResource modelConfig = new ModelConfigResource(); DRMClient.getInstance().register(modelConfig); modelConfigResource = modelConfig; lock.unlock(); } return modelConfigResource; }}
出现问题的流程:
a. 绿色的线程为第一个profile注册的线程,蓝色的线程为第二个profile注册的线程,并发请求进入。
b. 绿色实心为执行到的流程,蓝色实心为执行到的流程,白色为未执行到的流程。
c. 绿色prfoile线程进入后,执行到黄色代码段时,蓝色profile线程进入,此时profile中还没有值,因此会去执行lock.lock,因为lock被绿色线程所使用,所以等待此锁释放。
d. 绿色profile线程执行完,此时profile已经被赋值,蓝色线程执行lock.lock,获得锁,继续向下执行,执行到判断逻辑profile!=null, 此时不为null,直接return。
e. 此时蓝色线程中ReentrantLock锁是lock状态,此时锁没有被unlock,模型阀门配置想要获取锁注册资源时,会出现此锁一直是lock状态,无法获取此锁,导致一直无法注册资源。
修复后的代码:
public class CommonConfig { /** 非公平锁 */ private static ReentrantLock lock = new ReentrantLock(false); /** profile相关阀门控制*/ private ProfileConfigResource profileConfigResource; /** 模型相关阀门控制*/ private ModelConfigResource modelConfigResource; public ProfileConfigResource getProfileResource() { if (profileConfigResource == null) { try { lock.lock(); if (profileConfigResource != null) { return profileConfigResource; } ProfileConfigResource profileConfig = new ProfileConfigResource(); DRMClient.getInstance().register(profileConfig); profileConfigResource = profileConfig; } finally { lock.unlock(); } } return profileConfigResource; } public ModelConfigResource getModelResource() { if (modelConfigResource == null) { try { lock.lock(); if (modelConfigResource != null) { return modelConfigResource; } ModelConfigResource modelConfig = new ModelConfigResource(); DRMClient.getInstance().register(modelConfig); modelConfigResource = modelConfig; } finally { lock.unlock(); } } return modelConfigResource; }}
- 并发情况下ReentrantLock死锁
- 并发情况下synchronized死锁
- sql server中高并发情况下 同时执行select和update语句死锁问题 (一)
- sql server中高并发情况下 同时执行select和update语句死锁问题 (二)
- sql server中高并发情况下 同时执行select和update语句死锁问题
- sql server中高并发情况下 同时执行select和update语句死锁问题
- sql server中高并发情况下 同时执行select和update语句死锁问题 (二)
- sql server中高并发情况下同时执行select和update语句死锁问题(一)
- sql server中高并发情况下同时执行select和update语句死锁问题(二)
- sqlserver高并发情况下 select 和update操作造成死锁的解决方法
- sqlserver高并发情况下 select 和update操作造成死锁的解决方法
- JDK并发包---(4)重入锁ReentrantLock:锁申请无限等待且不会产生死锁
- IE6特定情况下的死锁
- 死锁情况
- 并发编程--互斥锁ReentrantLock
- java并发之ReentrantLock
- 【Java并发】- ReentrantLock,重入锁
- Java并发之ReentrantLock
- 将ClientDataset必须的midas.dll编译到程序中,避免Midas.dll与程序一起发布
- sqlalchemy 连接mysql 数据库问题
- C++中的引用
- 确定进制
- 3G门户笔试的一些思考 记于2013年09月25日
- 并发情况下ReentrantLock死锁
- Android在标准linux基础上对休眠唤醒的实现(wakelock)
- 转载:必须掌握的八个【cmd 命令行】
- 复习:HTML要注意的点
- POJ 1915 Knight Moves (广度搜索)
- 一个骰子,6面,1个面是 1, 2个面是2, 3个面是3,问平均掷多少次能使1、2、3都至少出现一次
- 当iBATIS新创建线程 调用数据层的时候 Could not obtain reference to HttpContext
- 文章啊文章,你不写文章真屈才啦,说的话句句经典!
- 关于C语言负数在内存中的存储