最近项目里面的一段千年代码出了问题,这个问题以前也出现过,不过不是那么明显,这次迁移机器由以前的4台机子变成2台以后问题被放大,最终不得不解决,特此分析一下。
先放出问题的代码
private AlimamaCodeDAO alimamaCodeDAO;
private Cache cache;
/**
* @param cache the cache to set
*/
public void setCache(Cache cache) {
this.cache = cache;
}
private Map codeMap; // KEYCODE与KEYNAME
public List<AlimamaCodeDO> getAlimamaCodeByKey(String key) throws BOException {
initCodeMap();
return (List<AlimamaCodeDO>) codeMap.get(key);
}
private void initCodeMap() throws BOException {
try {
//Element element = cache.get(CacheKeyConstants.ALIMAMACODE_KEY);
//if (element == null) {
List codes = alimamaCodeDAO.findAllAlimamaCode();
codeMap = new HashMap();
for (int i = 0; i < codes.size(); i++) {
AlimamaCodeDO codeDo = (AlimamaCodeDO) codes.get(i);
if (!codeMap.containsKey(codeDo.getKey())) {
List list = new ArrayList();
list.add(codeDo);
codeMap.put(codeDo.getKey(), list);
} else {
((List) codeMap.get(codeDo.getKey())).add(codeDo);
}
}
//element = new Element(CacheKeyConstants.ALIMAMACODE_KEY, (Serializable) codeMap);
//cache.put(element);
//}
//codeMap = (Map) element.getValue();
} catch (DAOException e) {
throw new BOException("获取系统编码表时出现异常", e);
}
}
这一段代码有点漏洞百出,在调用getAlimamaCodeByKey的时候,高并发下,会出现hashmap的死锁,导致cpu100%。至于这个代码为什么写出这样,就暂时不叙述了,就来分析一下出现死锁的原因是什么。
每一次调用getAlimamaCodeByKey的时候,首先是去初始化这个hashmap,在初始化时,这个hashmap
void transfer(Entry[] newTable) {
Entry[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry<K,V> e = src[j];
if (e != null) {
src[j] = null;
do {
Entry<K,V> next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
死锁就出现在了while (e != null);从上面的代码看来,每一个线程进来都先执行 codeMap = new HashMap();这个时候codeMap是空的,所以在执行下面的操作的时候进入了某一个不可以随意
更改状态的代码中,再加上高并发,一直被new HashMap(),while一直被执行,变成了死循环。cpu就瞬间飙升到100%,一直持续到请求数降低的时候。
最后解决办法:重构这部分代码,这部分代码本来就是写的不正确。再将HashMap改为ConcurrentHashMap,线程安全的Map。
线上观察很多天,一切正常。
分享到:
相关推荐
HashMap导致CPU100% 的分析
线程死锁 CPU过高 WeakHashMap 请求原因分析
20-集合框架020-HashMap-1080P 高清-AVC20
1.说一下 HashMap 的实现原理? 2.HashMap在JDK1.7和JDK1.8中有哪些不同?HashMap的底层实现? 3.HashMap的put方法的具体流程? 4.HashMap的扩容操作是怎么实现的? 5.HashMap是怎么解决哈希冲突的? 6.什么是哈希?...
Java、hashMap
A simple C hashmap
官方
泛型HashMap-Java Java的通用HashMap
Create Hash map and Hash function
java-HashMap-loop
dsa-hashmap-practice
grunt-hashmap-ext 更改 php 文件结果以返回数组而不是创建变量
看完这篇 HashMap,和面试官扯皮就没问题了 - HashMap 概述 - HashMap 和 HashTable 的区别 - 相同点 - 不同点 - HashMap 和 HashSet 的区别 - HashMap 底层结构 - AbstractMap 类 - Map 接口 - 重要内部类...
读取excel文件数据,封装成hashmap-附件资源
HashMap的用法---马克-to-win java视频的详细描述与介绍
hashmap的原理啊思想。
哈希映射线程测试使用 Maven 构建和运行 mvn exec:java
HashMap数据结构,HashMap的构造方法,HashMap的put,HashMap的get
详 解 hashmap 1.7 扩 容 机 制 的 数 据 迁 移 以 及 出 现 环 形 列 表 导 致 死 锁 情 况 视 频