业务背景:
系统启动时需要向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;
}
}
分享到:
相关推荐
5. **原子变量**:`java.util.concurrent.atomic`包中的原子变量类,如`AtomicInteger`、`AtomicLong`,提供了在不使用锁的情况下进行线程安全的操作。 6. **并发工具类**:`java.util.concurrent`包提供了许多实用...
而ReentrantLock则提供了更灵活的锁操作,支持公平锁与非公平锁,以及可中断和定时等待。 6. **原子变量**:Atomic类提供了一组原子操作,如AtomicInteger、AtomicBoolean等,它们在多线程环境下保证更新操作的原子...
通过深入学习"Java并发编程与实践"文档,开发者能够提升自己在高并发环境下的编程能力,设计出更加健壮和高效的Java应用程序。这份资料对于理解Java并发原理、优化并发代码和解决并发问题具有极大的价值。
高并发编程第三阶段04讲 利用CAS构造一个TryLock自定义显式锁-增强并发情况下.mp4 高并发编程第三阶段05讲 AtomicBoolean源码分析.mp4 高并发编程第三阶段06讲 AtomicLong源码分析.mp4 高并发编程第三阶段07...
- `java.util.concurrent.atomic`包下的原子类,如`AtomicInteger`、`AtomicLong`等,提供无锁的原子操作,支持在不使用锁的情况下进行线程安全的更新。 5. **并发编程模式** - **生产者-消费者模式**:使用`...
高并发编程第三阶段04讲 利用CAS构造一个TryLock自定义显式锁-增强并发情况下.mp4 高并发编程第三阶段05讲 AtomicBoolean源码分析.mp4 高并发编程第三阶段06讲 AtomicLong源码分析.mp4 高并发编程第三阶段07...
5. **原子类**:`java.util.concurrent.atomic`包中的原子类,如AtomicInteger、AtomicReference等,提供了一种在无锁情况下更新变量的方法,保证了在高并发环境下的数据一致性。 6. **并发设计模式**:了解如生产...
这在某些情况下非常有用,因为它可以避免由于错误地获取锁而导致的死锁问题。 **示例:** - `ReentrantLock`就是一种典型的可重入锁。 - `Synchronized`也是可重入锁的一种实现。 #### 三、独享锁与共享锁 **1. ...
此外,书中还讨论了Lock接口及其实现,如ReentrantLock,相比synchronized提供了更细粒度的锁控制和更丰富的特性,如尝试获取锁、可中断等待和公平锁等。这些高级锁机制能够帮助开发者写出更高效、更灵活的并发代码...
4. **并发集合**:Java并发集合库(java.util.concurrent包)提供了一系列线程安全的数据结构,如ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue等,它们在并发环境下具有高性能和高安全性。 5. **原子...
2. **并发控制**:Java提供了多种并发控制机制,如synchronized关键字、volatile变量、java.util.concurrent包下的锁和同步工具类(如ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier)。这些机制用于解决...
本资源摘要信息中,我们将详细介绍并发编程相关的知识点,涵盖线程、synchronized、volatile、CAS、Lock、ReentrantLock 等概念,并对相关知识点进行了详细的解释和比较。 线程 在 Java 中,线程是并发编程的基础...
另外,`ReentrantLock`是可重入锁,提供了比`synchronized`更灵活的锁定机制。 4. **并发容器**:`ArrayList`、`LinkedList`等集合在并发环境下可能存在安全问题,因此,Java提供了线程安全的集合类,如`Vector`、`...
- **java.util.concurrent.atomic包**:包含一系列原子类,如AtomicInteger、AtomicLong等,它们提供了在不使用锁的情况下实现原子更新的能力,适用于高并发场景。 - **compareAndSet()**:原子地比较并设置值,...
`java.util.concurrent.locks.Lock`接口提供比`synchronized`更灵活的锁定机制,如`ReentrantLock`实现了可重入锁,提供了更高的灵活性和效率。 #### 四、Java并发工具类 Java并发编程中常用的一些工具类,这些工具...
5. **并发设计模式**:书中的实例章节介绍了多种并发设计模式,如生产者消费者模型、读写锁策略、双检锁/双重校验锁(DCL)、线程局部变量等,这些模式为解决并发问题提供了模板化的解决方案。 6. **源码分析**:...
此外,Java的Lock接口和ReentrantLock等高级同步机制提供了比synchronized更精细的控制,允许开发者设计出更灵活的并发解决方案。 Java并发工具类库(java.util.concurrent)是并发编程中的另一个重要主题,包括...
- **java.util.concurrent.atomic包**:包含`AtomicInteger`, `AtomicLong`等类,提供在不使用锁的情况下实现原子操作的方法。 6. **线程池** - **线程池原理**:如何管理线程的创建、复用和销毁,以及任务的提交...
4. **原子变量类**:`java.util.concurrent.atomic`包下的原子变量类如`AtomicInteger`、`AtomicLong`等,它们提供了无锁的原子操作,可以在不使用锁的情况下实现线程安全的更新。 5. **线程池**:`ExecutorService...
2. **同步机制**:Java提供了多种同步工具,如synchronized关键字、Lock接口(包括ReentrantLock可重入锁)、Semaphore信号量、CountDownLatch倒计时器等。理解它们的工作原理和使用场景至关重要,因为这能防止数据...