HashMap的线程不安全特性导致死循环

在我们的理解中,线程不安全可能带来的问题是对一个对象的多写带来的数据不一致,可是万万没想到,由于HashMap的线程不安全特性,居然会出现CPU100%的情况。

 

最近我们生产环境就出现了这种情况,夜间的业务量并不大,一台机器的某个服务占用CUP飙升到了340%,于是我们切断了这台机器的业务,在没有业务的情况,这个服务的CPU占用仍然没有降下来。

抓了个dump,看看了线程栈的运行情况,发现这个服务的三个线程都在干同一件事,这个很诡异:

 

"qtp1660201379-122235" prio=5 tid=122235 RUNNABLE
	at java.util.HashMap.getEntry(HashMap.java:465)
	   Local Variable: java.util.HashMap$Entry#77179
	   Local Variable: java.lang.String#6513
	at java.util.HashMap.get(HashMap.java:417)
......

 

应该是这三个线程都在跑一个死循环,然后每个线程占用一颗CPU,正好把300%的CPU给占用了。查了下,由于HashMap的线程不安全特性,会在多线程对同一个HashMap做同一个操作的时候小概率引起死循环。

 

具体就是很多线程在对同一个HashMap进行读操作的时候,一个线程对这个对象在没有锁保护地进行写操作的时候,就会小概率引起死循环。

 

JAVA团队认为HashMap被标为线程不安全,在多线程情况下,出现这种问题属于正常,不算bug。

然后推荐大家在多线程环境下使用ConcurrentHashmap来替换HashMap。

 

具体死循环的原因分析见此文章:

http://coolshell.cn/articles/9606.html

没有更多推荐了,返回首页