并发情况下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;
}
}
并发情况下synchronized死锁的更多相关文章
- Jackson高并发情况下,产生阻塞
情况:在高并发情况下,查看线程栈信息,有大量的线程BLOCKED. 从线程栈得知,线程栈中出现了阻塞,锁在了com.fasterxml.jackson.databind.ser.SerializerC ...
- PHP通过加锁实现并发情况下抢码实现
需求:抢码功能 要求: 1.特定时间段才开放抢码: 2.每个时间段放开的码是有限的: 3.每个码不允许重复: 实现: 1.在不考虑并发的情况下实现: function get_code($len){ ...
- 关于WCF服务在高并发情况下报目标积极拒绝的异常处理
最近弄了个wcf的监控服务,偶尔监控到目标服务会报一个目标积极拒绝的错误.一开始以为服务停止了,上服务器检查目标服务好好的活着.于是开始查原因. 一般来说目标积极拒绝(TCP 10061)的异常主要是 ...
- 解决并发情况下库存减为负数问题--update2016.04.24
场景: 一个商品有库存,下单时先检查库存,如果>0,把库存-1然后下单,如果<=0,则不能下单,事务包含两条sql语句: ; update products ) WHERE id=; 在并 ...
- WCF服务在高并发情况下报目标积极拒绝的异常处理 z
http://www.cnblogs.com/kklldog/p/5037006.html wcf的监控服务,偶尔监控到目标服务会报一个目标积极拒绝的错误.一开始以为服务停止了,上服务器检查目标服务好 ...
- Linux的虚拟内存管理-如何分配和释放内存,以提高服务器在高并发情况下的性能,从而降低了系统的负载
Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全 ...
- 高并发情况下分布式全局ID
1.高并发情况下,生成分布式全局id策略2.利用全球唯一UUID生成订单号优缺点3.基于数据库自增或者序列生成订单号4.数据库集群如何考虑数据库自增唯一性5.基于Redis生成生成全局id策略6.Tw ...
- PHP通过加锁实现并发情况下抢码功能
本文基于php语言使用加锁实现并发情况下抢码功能,特定时间段开放抢码并不允许开放的码重复: 需求:抢码功能 要求: 1.特定时间段才开放抢码: 2.每个时间段放开的码是有限的: 3.每个码不允许重复: ...
- c# redis 利用锁(StackExchange.Redis LockTake)来保证数据在高并发情况下的正确性
之前有写过一篇介绍c#操作redis的文章 http://www.cnblogs.com/axel10/p/8459434.html ,这篇文章中的案例使用了StringIncrement来实现了高并 ...
随机推荐
- 四、Solr数据源配置(JNDI、DIH)及定时重做索引
简介 Solr支持很多种创建索引的方式,包括网页,xml以及数据库,因为我这边做的是企业级的搜索,所以用的是数据库建立索引.其实从数据库建立索引,很大程度上取决于原来的数据库设计. 从数据库建立索引, ...
- paip.提升用户体验---c++ qt 取消gcc编译的警告信息.txt
paip.提升用户体验---c++ qt 取消gcc编译的警告信息.txt 作者Attilax , EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http:// ...
- shell脚本加密
如何保护自己编写的shell程序要保护自己编写的shell脚本程序,方法有很多,最简单的方法有两种:1.加密 2.设定过期时间,下面以shc工具为例说明: 一.下载安装shc工具shc是一个加密s ...
- SQLite中不支持的sql语法
今天很自然的在写Sql语句的时候用了Top,一开始没发现问题,因为我从数据库读出的值正好是0,而我习惯变量定义的时候也都赋值0,可是到我不要0的时候我就发现问题了.后来才知道,可爱的小sqlite竟然 ...
- linux修改主机名-IP
1.查看当前主机名 hostname 2. ifconfig 显示所有网络接口的信息 ifconfig eth0 显示网卡eth0的信息 3.临时修改主机名 hostname rusky. ...
- ubuntu安装python3.5
ubuntu14.04系统会自带python2.7,请不要卸载它.不同版本的Python可以共存在一个系统上. 卸载之后,桌面系统会被影响. (1)sudo add-apt-repository pp ...
- 解决操作过快导致ajax异常的办法
//控制点击过快ajax异常 var state = true; function test() { if (state) { state = false; var val = accMul((uCo ...
- C# typeof Gettype is as &拆箱 装箱
有时候,我们不想用值类型的值,就是想用一个引用..Net提供了一个名为装箱(boxing)的机制,它允许根据值类型来创建一个对象,然后使用对这个新对象的一个引用. 首先,回顾两个重要的事实,1.对于引 ...
- C# XML流操作简单实例
这里我们先介绍操作XML文件的两个对象:XmlTextReader和XmlTextWriter打开和读取Xml文件使用到的对象就是XmlTextReader对象.下面的例子打开了与程序在同一路径下的一 ...
- iOS 中实现随机颜色
开发中为了测试能够快速看到效果很多时候我们对颜色采用随机颜色 代码块如下 UIColor * randomColor= [UIColor colorWithRed:((float)arc4random ...