`
he91_com
  • 浏览: 416872 次
文章分类
社区版块
存档分类
最新评论

并发情况下ReentrantLock锁死锁

 
阅读更多

业务背景:

系统启动时需要向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;
    }

}
分享到:
评论

相关推荐

    精心整理的AQS和JUC相关的面试题.pdf【ReentrantLock】

    通常情况下,非公平锁的性能更高,但公平锁可以避免某些线程饿死的情况。 ReentrantLock还提供了Condition对象,这是一种比Object的wait/notify更加灵活的机制,允许线程以一种排队的方式来等待某个条件成立,并且...

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段04讲 利用CAS构造一个TryLock自定义显式锁-增强并发情况下.mp4  高并发编程第三阶段05讲 AtomicBoolean源码分析.mp4  高并发编程第三阶段06讲 AtomicLong源码分析.mp4  高并发编程第三阶段07...

    并发编程的艺术

    而ReentrantLock则提供了更灵活的锁操作,支持公平锁与非公平锁,以及可中断和定时等待。 6. **原子变量**:Atomic类提供了一组原子操作,如AtomicInteger、AtomicBoolean等,它们在多线程环境下保证更新操作的原子...

    java并发编程与实践

    通过深入学习"Java并发编程与实践"文档,开发者能够提升自己在高并发环境下的编程能力,设计出更加健壮和高效的Java应用程序。这份资料对于理解Java并发原理、优化并发代码和解决并发问题具有极大的价值。

    汪文君高并发编程实战视频资源全集

     高并发编程第三阶段04讲 利用CAS构造一个TryLock自定义显式锁-增强并发情况下.mp4  高并发编程第三阶段05讲 AtomicBoolean源码分析.mp4  高并发编程第三阶段06讲 AtomicLong源码分析.mp4  高并发编程第三阶段07...

    Java高并发实践

    5. **原子类**:`java.util.concurrent.atomic`包中的原子类,如AtomicInteger、AtomicReference等,提供了一种在无锁情况下更新变量的方法,保证了在高并发环境下的数据一致性。 6. **并发设计模式**:了解如生产...

    Java锁的种类以及区别

    这在某些情况下非常有用,因为它可以避免由于错误地获取锁而导致的死锁问题。 **示例:** - `ReentrantLock`就是一种典型的可重入锁。 - `Synchronized`也是可重入锁的一种实现。 #### 三、独享锁与共享锁 **1. ...

    Java并发编程实践 高清扫描版

    此外,书中还讨论了Lock接口及其实现,如ReentrantLock,相比synchronized提供了更细粒度的锁控制和更丰富的特性,如尝试获取锁、可中断等待和公平锁等。这些高级锁机制能够帮助开发者写出更高效、更灵活的并发代码...

    ( java并发编程.zip )文字版 电子书 高清版

    4. **并发集合**:Java并发集合库(java.util.concurrent包)提供了一系列线程安全的数据结构,如ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue等,它们在并发环境下具有高性能和高安全性。 5. **原子...

    并发编程 70 道面试题及答案.docx

    本资源摘要信息中,我们将详细介绍并发编程相关的知识点,涵盖线程、synchronized、volatile、CAS、Lock、ReentrantLock 等概念,并对相关知识点进行了详细的解释和比较。 线程 在 Java 中,线程是并发编程的基础...

    Java高并发经典文档-PDF-可在电子书里查看

    另外,`ReentrantLock`是可重入锁,提供了比`synchronized`更灵活的锁定机制。 4. **并发容器**:`ArrayList`、`LinkedList`等集合在并发环境下可能存在安全问题,因此,Java提供了线程安全的集合类,如`Vector`、`...

    通过多线程编程在Java中发现的并发模式和特性——线程、锁、原子等.zip

    - **java.util.concurrent.atomic包**:包含一系列原子类,如AtomicInteger、AtomicLong等,它们提供了在不使用锁的情况下实现原子更新的能力,适用于高并发场景。 - **compareAndSet()**:原子地比较并设置值,...

    java并发编程实践

    `java.util.concurrent.locks.Lock`接口提供比`synchronized`更灵活的锁定机制,如`ReentrantLock`实现了可重入锁,提供了更高的灵活性和效率。 #### 四、Java并发工具类 Java并发编程中常用的一些工具类,这些工具...

    JAVA并发编程实践.pdf

    4. **原子变量类**:`java.util.concurrent.atomic`包下的原子变量类如`AtomicInteger`、`AtomicLong`等,它们提供了无锁的原子操作,可以在不使用锁的情况下实现线程安全的更新。 5. **线程池**:`ExecutorService...

    《java并发编程实践》

    2. **同步机制**:Java提供了多种同步工具,如synchronized关键字、Lock接口(包括ReentrantLock可重入锁)、Semaphore信号量、CountDownLatch倒计时器等。理解它们的工作原理和使用场景至关重要,因为这能防止数据...

    JAVA并发编程实践.zip

    8. **原子操作与Atomic类**:Java提供了一系列Atomic类,如AtomicInteger、AtomicLong等,它们的原子方法支持在不使用锁的情况下进行原子更新,提高了并发性能。 9. **并发编程模式**:包括生产者消费者模型、读写...

    Java并发程序设计+并发

    - **Lock接口与ReentrantLock**:比`synchronized`更灵活,支持公平锁和非公平锁,提供锁获取和释放的显式控制。 3. **线程通信**: - **wait()、notify()和notifyAll()**:基于对象监视器的通信方式,需在同步块...

    Java 并发编程实战

    并发编程是现代多核处理器环境下软件开发的重要组成部分,它涉及到线程、同步、锁、并发集合等核心概念,对于提升程序的效率和性能至关重要。下面将详细阐述Java并发编程中的关键知识点。 1. **线程基础**:在Java...

    Java 多线程与并发-Java并发知识体系详解.pdf

    Java并发工具包J.U.C(Java Util Concurrency)包含了丰富的一系列并发组件,如Lock框架(ReentrantLock等)、并发集合(ConcurrentHashMap等)、原子类(AtomicInteger等)、线程池(ExecutorService)和工具类。...

    java并发编程实战源码,java并发编程实战pdf,Java源码.zip

    - **读写锁**:在多读少写的情况下提高性能,如`ReadWriteLock`接口及其实现类`ReentrantReadWriteLock`。 6. **线程安全问题** - **死锁**:两个或更多线程相互等待对方释放资源,导致都无法继续执行。 - **...

Global site tag (gtag.js) - Google Analytics