不正确使用HashMap,造成CPU 100%的问题
来源:互联网 发布:mac跟淘宝客服聊天 编辑:程序博客网 时间:2024/06/14 02:17
参考各类blog
【不正确使用HashMap,造成CPU 100%的问题】和一些关于多线程的技术文档【浅谈Java多线程的同步问题】。
分析了一下.
先列出问题的代码:
public class DataManager {
......
private Map<Object, Integer> fStyleCache = new HashMap<Object, Integer>();
private Map<Object, Integer> fSkuCache = new HashMap<Object, Integer>();
......
public static void initialize() {
WorkerQueue q = new WorkerQueue();
..........
q.add(new DBWorker() {
@Override
protected void process()
throws Exception
{
DataManager dm = getInstance(this);
dm.getBaseSscDataUnit(dm.getBasePOSStartEndMonth(), this);
}
});
q.add(new DBWorker() {
@Override
protected void process()
throws Exception
{
DataManager dm = getInstance(this);
dm.getBaseSscDcDataUnit(dm.getBasePOSStartEndMonth(), this);
}
});
/*q.add(new DBWorker() {
@Override
protected void process()
throws Exception
{
DataManager dm = getInstance(this);
dm.getBaseProdAttrDataUnit(this);
}
});
*/
q.start();
}
..........
private StyleSkuCountDataUnit getBaseSscDataUnit(int[] posStartEndMonth, DBConnection dc)
throws SQLException
{
synchronized(fSscDataUnit) {
if(fSscDataUnit.IsNeedRetrieveDBAgain()) {
fSscDataUnit = this.buildSscDataUnit(......);//此方法调用getStyleSkuFromCache
fSscDataUnit.setIsNeedRetrieveDBAgain(false);
}
}
return fSscDataUnit;
}
private StyleSkuCountDataUnit getBaseSscDcDataUnit(int[] posStartEndMonth, DBConnection dc)
throws SQLException
{
synchronized(fSscDcDataUnit) {
if(fSscDcDataUnit.IsNeedRetrieveDBAgain()) {
fSscDcDataUnit = this.buildSscDcDataUnit(.......);//此方法调用getStyleSkuFromCache
fSscDcDataUnit.setIsNeedRetrieveDBAgain(false);
}
}
return fSscDcDataUnit;
}
private Integer getStyleSkuFromCache(Object styleSku, boolean isStyle){
Map<Object, Integer> cache = null;
if(isStyle){
cache = fStyleCache; //HashMap
}else{
cache = fSkuCache; //HashMap
}
Integer value = cache.get(styleSku);
if(null == value){
value = cache.size();
cache.put(styleSku, value);
}
return value;
}
}
每一次调用getStyleSkuFromCache的时候,会向cache的map中put value. 而从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
);
}
}
}
从上面的代码看来,每一个线程进来都先执行.一开始fStyleCache ,fSkuCache是空的,两个线程在执行上面的do{} 操作同一个cache的map
,校验while (e != null) 时出现同步问题,
e.next读的是对方线程刚put的value 这样
e.next
一直不为null,
while一直被执行,变成了死循环。cpu就瞬间飙升到100%.总之,就是多线程操作(主要是修改map结构)同一个map导致内部map数据结构紊乱。解决办法:
1.将HashMap改为ConcurrentHashMap,线程安全的Map。
2.对此方法 getStyleSkuFromCache(Object styleSku, boolean isStyle) 进行同步控制,单线程执行此方法。
- 不正确使用HashMap,造成CPU 100%的问题
- 不正确使用HashMap,造成CPU 100%的问题
- 使用HashMap线程不安全造成CPU 100%
- 不正确使用HashMap造成死循环及元素丢失--转载
- 不正当使用HashMap导致cpu 100%的问题追究
- 不正当使用HashMap导致cpu 100%的问题追究(HashMap死循环探究)
- 造成CPU使用100%的几个原因(转载)
- 不正确的使用HashMap引发死循环及元素丢失
- 【原创】Apache在linux AS3上使用会造成CPU使用率达到100%问题一例
- Java中HashMap造成的死循环问题
- 小议 Thread.sleep(0) 造成 CPU占用率高的问题
- Android CPU使用过大的问题解决以及造成的原因
- 使用多进程会造成的问题
- java多线程使用不当造成的问题
- 关于HashMap的使用问题
- ScrollView里嵌套Recycleview使用StaggeredGridLayoutManager高度不正确的问题
- hashmap碰撞 造成的死循环
- 造成HashMap非线程安全的原因
- 什么是锚文本
- 百钱买百鸡
- Android fill_parent和wrap_content分析
- [收集]虚继承
- mysql-HandlerSocket的原理
- 不正确使用HashMap,造成CPU 100%的问题
- Xcode 4.5 支持 amv6
- Android软键盘弹出不影响布局的方法
- String类的工作原理
- mysql-HandlerSocket的优势和缺陷阐述
- Acclerated C++ 第2章
- Spring 实现 定时任务(两种)
- 百度lbs的使用
- 正确的关机方法: sync, shutdown, reboot, halt, poweroff, init