博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java之多线程(1) - Race Condition引起的性能问题
阅读量:7239 次
发布时间:2019-06-29

本文共 1449 字,大约阅读时间需要 4 分钟。

Race Condition(也叫做资源竞争),是多线程编程中比较头疼的问题。特别是Java多线程模型当中,经常会因为多个线程同时访问相同的共享数据,而造成数据的不一致性。为了解决这个问题,通常来说需要加上同步标志“synchronized”,来保证数据的串行访问。但是“synchronized”是个性能杀手,过多的使用会导致性能下降,特别是扩展性下降,使得你的系统不能使用多个CPU资源。  这是我们在性能测试中经常遇见的问题。

可是上个星期我却遇见了相反的情况:因为缺少同步标志也同样会使性能受影响。

那是一个ERP系统,运行在我们的T2000服务器(8核32线程)上。当500个并发用户的时候居然把所有的CPU都压得满满的(90%以上的忙碌)。这是很少有的现象,在我测试的所有项目中很少有扩展性这么好的系统能把T2000的32个线程都占满的。我狠狠的夸了他们的应用。话音没落,却发现测试结果很差,平均响应时间很长。不可能呀,所有的CPU都在干活,而且都在用户态(如果在系统态干太多的活就有问题了),结果怎么还会差呢。CPU都在干嘛呢?

通过工具发现(Dtrace for Java),我们发现很多的CPU都在做一件事情,那就是不停的执行一条Java语句(HashMap.get())。象是进入了死循环。我们进行了进一步试验,让并发用户数量为1,不停的运行10分钟,结果没有发现这种情况;接着我们让50个并发用户同时运行,但是只运行在一个CPU上(通过psrset),结果也没有出现死循环状态。只要并发用户数量超过10个,运行的CPU超过两个,不到2分钟就出现死循环。一旦死循环出现,大量CPU资源被白白浪费,性能自然很差。

通过上面的试验我们可以很肯定的判断,是由于并发控制不好,导致数据的不一致,引起的死循环。值得一提的是,HashMap不是一个线程安全的数据结构,要用到多个线程中去,需要自己加上同步标志,为什么会死循环呢,看看下面HashMap中get函数的源代码:

public V get(Object key) { if (key == null)     return getForNullKey();        int hash = hash(key.hashCode());        for (Entry
e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }

get函数会根据key的hashcode来锁定多个对象,并且遍历这些对象来找到key所对应的对象。当多个线程不安全的修改HanshMap数据结构的时候,有可能使得这个函数进入死循环。

我们建议客户使用ConcurrentHashMap或在使用HanshMap的时候加上同步标志,问题得到解决!

 

转载于:https://www.cnblogs.com/royi123/archive/2013/06/06/3122848.html

你可能感兴趣的文章
嵌入式第十二次
查看>>
第8课 - 条件判断语句
查看>>
【Unity】9.2 如何添加粒子组件
查看>>
U盘容量足够,但在拷贝时提示“文件太大”无法拷贝时怎么办
查看>>
Android开源项目分类汇总
查看>>
解决windows7蓝屏的方法
查看>>
将NASM汇编器集成到Visual Studio中
查看>>
linux设置自动更换壁纸
查看>>
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
查看>>
pandas安装过程中提示unable to find vcvarsall.bat的解决方法
查看>>
RestTemplate--解决中文乱码
查看>>
launch edge和latch edge延迟
查看>>
关于Android studio Logcat显示不全,不显示自己需要打印的LOG数据
查看>>
微信小程序--问题汇总及详解之tab切换
查看>>
篇1 安卓app自动化测试-appium环境篇
查看>>
html5 拖拽练习题
查看>>
kvc(键-值编码)
查看>>
设置UITableView边框
查看>>
Spring JDBC 数据访问
查看>>
sql优化经历(转存+记录)
查看>>