HashMap的线程不安全特性导致死循环
程序员文章站
2024-03-13 13:14:45
...
在我们的理解中,线程不安全可能带来的问题是对一个对象的多写带来的数据不一致,可是万万没想到,由于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