业务背景:
系统启动时需要向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;
}
}
分享到:
相关推荐
主要介绍了Java并发编程之显示锁ReentrantLock和ReadWriteLock读写锁,本文讲解了ReentrantLock概况、Lock接口、Lock使用、轮询锁的和定时锁、公平性、可中断获锁获取操作等内容,需要的朋友可以参考下
而且ReentrantLock相比synchronized而言功能更加丰富,使用起来更为灵活,也更适合复杂的并发场景。这篇文章主要是从使用的角度来分析一下ReentrantLock。 ReentrantLock与synchronized来的区别 1.synchronized是...
深入java并发编程,使用ReentrantLock和 Synchronized加锁
主要为大家详细介绍了Java并发系列之ReentrantLock源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
java语言 并发编程 ReentrantLock与synchronized区别 详解
主要为大家详细介绍了Java并发系列之ReentrantLock源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
Java 多线程与并发(11_26)-JUC锁_ ReentrantLock详解
ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。下面我们来深入了解一下它吧
【Java并发】当年因为Reentrantlock被拒,今天把它源码里里外外给扒了
带你看看Javad的锁-ReentrantLock前言ReentrantLock简介Synchronized对比用法源码分析代码结构方法分析SyncNonfairSyncFairSync非公平锁VS公平锁什么是公平非公平ReentrantLockReentrantLock的构造函数lock加锁方法...
ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。在java关键字synchronized隐式支持重...
java中的乐观锁与悲观锁,synchronized与ReentrantLock重入锁的说明与比较
主要介绍了Java多线程 ReentrantLock互斥锁详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
主要介绍了java并发之重入锁-ReentrantLock,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
private static class MyReentrantLock extends ReentrantLock {public MyReentrantLo
1、ReentrantLock简介 2、ReentrantLock函数列表 3、重入的实现 4、公平锁与非公平锁 5、ReentrantLock 扩展的功能 6
同步机制:讲解如何使用锁、信号量、原子操作等同步机制来避免竞态条件和死锁。 并发模型:介绍不同的并发模型,如生产者-消费者模型、管道模型、消息传递模型等。 并发工具:介绍并发编程中使用的工具和库,如...
1、本资源包含并发编程基础知识的使用案例,包括:线程创建、Synchronized和Reentrantlock锁的使用、线程安全问题演示、Condition的应用、CountDownLatch的应用、Cyclicbarrier的应用、Semaphore的应用、线程池的...
主要介绍了ReentrantLock源码之条件锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面我们来一起学习一下吧
ReentrantLock的使用及注意事项