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

并发情况下synchronized死锁

 
阅读更多

存在缺陷的代码:

public class DataPropertyIdAndNameRepositoryImpl{
    /** 发布标志 */
    private volatile boolean                      publishFlag;

    public Integer getStandardId(int dataId, String propertyName) {
        if (!publishFlag) {
            loadToCache();
        }
        Integer standardId = 0;
        Map<String, Integer> propertyIdMap = propertyIdLocalCache.get(dataId);
        if (propertyIdMap != null) {
            standardId = propertyIdMap.get(propertyName);
        }
        return standardId;
    }

    public synchronized boolean loadToCache() {
        try {
            DataPropertyIdAndName dataPropertyIdAndName = dataPropertyIdAndNameService
                .queryDataPropertyIdAndName();
            publishFlag = true;
        } catch (Exception e) {
            publishFlag = false;
        }
        return publishFlag;
    }
}

存在缺陷的流程:

a. 绿色表示第一个线程,蓝色表示第二个线程。

b. 黄色模块的代码为synchronized标记的代码,并发情况下只会有一个线程执行此方法。

c. 绿色线程执行到紫色模块时,蓝色线程等待进入黄色模块。

d. 蓝色线程执行抛异常,导致publishFlag被置为false。

e. 此时再次有线程进入,判断publishFlag仍为false,因此导致重复不断加载loadToCache.



修复后的代码:

public class DataPropertyIdAndNameRepositoryImpl{
    /** 发布标志 */
    private volatile boolean                      publishFlag;

    public Integer getStandardId(int dataId, String propertyName) {
        if (!publishFlag) {
            loadToCache();
        }
        Integer standardId = 0;
        Map<String, Integer> propertyIdMap = propertyIdLocalCache.get(dataId);
        if (propertyIdMap != null) {
            standardId = propertyIdMap.get(propertyName);
        }

        return standardId;
    }

    public synchronized boolean loadToCache() {
        try {

            // 双检锁
            if (publishFlag) {
                return publishFlag;
            }

            DataPropertyIdAndName dataPropertyIdAndName = dataPropertyIdAndNameService.queryDataPropertyIdAndName();
            publishFlag = true;

        } catch (Exception e) {
            publishFlag = false;
        }

        return publishFlag;
    }
}




分享到:
评论

相关推荐

    Java并发教程.md

    [并发](#并发) * [synchronized](#synchronized) * [synchronized底层原理](#synchronized底层原理) * [synchronized 使用方法](#synchronized-使用方法) * [Synchronized和ReentrantLock的区别](#synchronized...

    Lock接口与synchronized关键字

    Lock接口与synchronized关键字在Java并发编程中都是用于实现同步机制的重要工具,但它们在使用方式、功能特性以及灵活性等方面存在一些显著的差异。...然而,在高度竞争的并发场景下,Lock接口可能会表现

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

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

    JAVA高质量并发详解,多线程并发深入讲解

    接着,深入讲解了Java并发编程的核心API,如synchronized关键字、Lock接口、Condition接口、Semaphore等,帮助读者掌握Java并发编程的基本工具和方法。 除了基础知识和API的讲解,本书还重点介绍了Java并发编程的...

    java高并发相关知识点.docx

    死锁:Java中的死锁,包括如何避免死锁和如何解除死锁。 性能优化:Java中的性能优化,包括JVM参数调优、代码优化、使用并发框架等。 并行计算:Java中的并行计算,包括Fork/Join框架、并行流等。 线程间通信:Java...

    java并发编程

    此外,本书还提供了有关并发编程的全方位的详细内容,例如限制和同步、死锁和冲突、依赖于状态的操作控制、异步消息传递和控制流、协作交互,以及如何创建基于web的服务和计算型服务。 本书的读者对象是那些希望掌握...

    Java并发编程:设计原则与模式(第二版)

    读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制和同步、...

    Java并发编程原理与实战

    理解自旋锁,死锁与重入锁.mp4 深入理解volatile原理与使用.mp4 JDK5提供的原子类的操作以及实现原理.mp4 Lock接口认识与使用.mp4 手动实现一个可重入锁.mp4 AbstractQueuedSynchronizer(AQS)详解.mp4 使用AQS重写...

    高级开发并发面试题和答案.pdf

    面试高级开发的期间整理的面试题目,记录我面试遇到过的并发题目以及答案 目录 并发 常说的并发问题是哪些;资源竞争、死锁、事务、可见性 死锁 如何排查死锁; 产生死锁的必要条件: 如何解决解决死锁; 锁 AQS:...

    java并发编程理论基础精讲

    死锁和解决: 介绍死锁的概念,解释死锁产生的原因和充要条件。 并发编程模型: 介绍不同的并发编程模型,如多生产者多消费者、读者写者、线程池等。 volatile 关键字: 解释 volatile 关键字的作用,探讨如何使用 ...

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

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

    龙果java并发编程完整视频

    第17节理解自旋锁,死锁与重入锁00:24:58分钟 | 第18节深入理解volatile原理与使用00:28:30分钟 | 第19节JDK5提供的原子类的操作以及实现原理00:27:10分钟 | 第20节Lock接口认识与使用00:19:54分钟 | 第21节手动...

    java并发编程面试题

    ,如何避免线程死锁 线程的 run()和 start()有什么区别? 什么是 Callable 和 Future? 线程的调度策略 sleep() 和 wait() 有什么区别? 什么是线程同步和线程互斥,有哪几种实现方式? Java 线程数过多会造成什么...

    java中的并发和多线程编程中文版

    读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制和同步、...

    并发编程面试专题.pdf

    6)用 Java 编程一个会导致死锁的程序,你将怎么解决? 7) 什么是原子操作,Java 中的原子操作是什么? 8) Java 中的 volatile 关键是什么作用?怎样使用它?在 Java 中它跟 synchronized 方法有什么不同? 9) 什么...

    Java并发编程实战

    13.4 在synchronized和ReentrantLock之间进行选择234 13.5 读-写锁235 第14章 构建自定义的同步工具238 14.1 状态依赖性的管理238 14.1.1 示例:将前提条件的失败传递给调用者240 14.1.2 示例:通过轮询与休眠...

    深入理解高并发编程-核心技术原理

    (1)【高并发】优化加锁方式时竟然死锁了!!》 (2)讲讲什么是缓存穿透?击穿?雪崩?如何解决? (3)Java中提供了synchronized,为什么还要提供Lock呢? 5、系统架构篇 (1) 高并发分布式锁架构解密,不是所有的...

    Java 并发编程原理与实战视频

    第17节理解自旋锁,死锁与重入锁00:24:58分钟 | 第18节深入理解volatile原理与使用00:28:30分钟 | 第19节JDK5提供的原子类的操作以及实现原理00:27:10分钟 | 第20节Lock接口认识与使用00:19:54分钟 | 第21节手动...

    龙果 java并发编程原理实战

    第17节理解自旋锁,死锁与重入锁00:24:58分钟 | 第18节深入理解volatile原理与使用00:28:30分钟 | 第19节JDK5提供的原子类的操作以及实现原理00:27:10分钟 | 第20节Lock接口认识与使用00:19:54分钟 | 第21节手动...

Global site tag (gtag.js) - Google Analytics