【多线程同步案例】Race Condition引起的性能问题
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<K,V> 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的时候加上同步标志,问题得到解决!
【多线程同步案例】Race Condition引起的性能问题的更多相关文章
- C#多线程同步案例实操
好久没有写博客了,为了养成学习的习惯,培养积极年轻的心态,又回到了博客园这个平台继续撸起时隔多年未光顾的空间. 项目需求: 实现一个简单的获取始发目的耗时.距离,将结果输出表格. 方案思路: 通过多线 ...
- 通过Lock对象以及Condition对象实现多线程同步
通过Lock对象以及Condition对象实现多线程同步: 在之前的学习中,无论是通过synchronized建立同步代码块,还是通过synchronized建立同步函数,都是把对象看成一把锁来实现同 ...
- java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: package com.zejian.test; /** * @author ...
- Fortify Audit Workbench 笔记 Race Condition: Singleton Member Field 竞争条件:单例的成员字段
Race Condition: Singleton Member Field 竞争条件:单例的成员字段 Abstract Servlet 成员字段可能允许一个用户查看其他用户的数据. Explanat ...
- Linux多线程同步方式
当多个线程共享相同的内存时,需要确保每个线程看到一致的数据视图,当多个线程同时去修改这片内存时,就可能出现偏差,得到与预期不符合的值.为啥需要同步,一件事情逻辑上一定是有序的,即使在并发环境下:而操作 ...
- C# 多线程同步和线程通信
多线程通信 1. 当线程之间有先后的依赖关系时,属于线程之间的通信问题.也就是后一个线程要等待别的一个或多个线程全部完成,才能开始下一步的工作.可以使用: WaitHandle Class WaitH ...
- Linux多线程同步机制
http://blog.163.com/he_junwei/blog/static/19793764620141711130253/ http://blog.csdn.net/h_armony/art ...
- 起底多线程同步锁(iOS)
iOS/MacOS为多线程.共享内存(变量)提供了多种的同步解决方案(即同步锁),对于这些方案的比较,大都讨论了锁的用法以及锁操作的开销,然后就开销表现排个序.春哥以为,最优方案的选用还是看应用场景, ...
- [一个经典的多线程同步问题]解决方案一:关键段CS
前面提出了一个经典的多线程同步互斥问题,本篇将用关键段CRITICAL_SECTION来尝试解决这个问题. 本文先介绍如何使用关键段,然后再深层次的分析下关键段的实现机制和原理. 关键段CRITICA ...
随机推荐
- POJ 3693 (后缀数组) Maximum repetition substring
找重复次数最多的字串,如果有多解,要求字典序最小. 我也是跟着罗穗骞菊苣的论文才刷这道题的. 首先还是枚举一个循环节的长度L,如果它出现两次的话,一定会包含s[0], s[L], s[2L]这些相邻两 ...
- 51nod1215 数组的宽度
傻叉单调栈 #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> ...
- jquery总结(1)
jquery是一种js对象.里面封装了一些方法,但是jquery对象不能直接使用js方法,js对象不能直接使用jquery方法. jquery对象类似于js对象的集合,就是存在形式是以特殊数组的形式: ...
- POJ 3692 Kindergarten (补图是二分图的最大团问题)
题意 幼稚园里有m个男孩和n个女孩(m.n范围都是[1,200]),男孩之间相互认识,女孩之间也相互认识,另外有部分男孩和女孩也认识.现在要举办一个活动,选取一些同学,要求所有选取的同学之间两两相互认 ...
- 一些纯css3写的公司logo
随着对css3了解得越深入,越来越发现了css3的强大.css3不但能完成一些基本的特效如圆角阴影等,还能借助动画技术实现一些复杂的动画,能替代很多以前js才能完成的工作,css3的作用还不止于此 ...
- 凸优化简介 Convex Optimization Overview
最近的看的一些内容好多涉及到凸优化,没时间系统看了,简单的了解一下,凸优化的两个基本元素分别是凸函数与凸包 凸集 凸集定义如下: 也就是说在凸集内任取两点,其连线上的所有点仍在凸集之内. 凸函数 凸函 ...
- over-fitting、under-fitting 与 regularization
机器学习中一个重要的话题便是模型的泛化能力,泛化能力强的模型才是好模型,对于训练好的模型,若在训练集表现差,不必说在测试集表现同样会很差,这可能是欠拟合导致:若模型在训练集表现非常好,却在测试集上差强 ...
- 五个JS经典面试题
1:Scope作用范围 1: (function() { 2: var a = b = 5; 3: })(); 4: 5: console.log(b); 什么会被打印在控制台上? 回答 上面的代码会 ...
- Android 一步一步教你使用ViewDragHelper
在自定义viewgroup的时候 要重写onInterceptTouchEvent和onTouchEvent 这2个方法 是非常麻烦的事情,好在谷歌后来 推出了ViewDragHelper这个类.可以 ...
- Scala下载安装配置(Mac)
---恢复内容开始--- 1.访问scala的官网这里下载最新版的scala. 2.解压缩文件包,可将其移动至/usr/local/share下 1 mv /download/scalapath /u ...