(
1
)
线
程不安全的
HashMap
在多
线
程
环
境下,使用
HashMap
进
行
put
操作会引起死循
环
,
导
致
CPU
利用率接近
100%
,所 以在并发
情况下不能使用
HashMap
。HashMap在并发执行put操作时会引起死循环,是因为多线程会导致HashMap的Entry链表 形成环形数据结构,一旦形成环形数据结构,Entry的next节点永远不为空,就会产生死循环获 取Entry
public class ConcurrentHashMap {
public static void main(String[] args) {
final HashMap<String,String> map = new HashMap<>(2);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
new Thread(new Runnable() {
@Override
public void run() {
map.put(UUID.randomUUID().toString(),"");
}
},"ftf" + i).start();
}
}
},"ftf");
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(
2
)效率低下的
HashTable
HashTable
容器使用
synchronized
来保
证线
程安全,但在
线
程
竞
争激烈的情况下
HashTable 的效率非常低下。因为
当一个
线
程
访问
HashTable
的同步方法,其他
线
程也
访问
HashTable
的同 步方法时
,会
进
入阻塞或
轮询
状
态
。如
线
程
1
使用
put
进
行元素添加,
线
程
不但不能使用
put
方
法添加元素,也不能使用
get
方法来
获
取元素,所以
竞
争越激烈效率越低。
(
3
)
ConcurrentHashMap
的
锁
分段技
术
可有效提升并
发访问
率
HashTable
容器在
竞
争激烈的并
发环
境下表
现
出效率低下的原因是所有
访问
HashTable
的 线程都必
须竞
争同一把
锁
,假如容器里有多把
锁
,每一把
锁
用于
锁
容器其中一部分数据,那么 当多线
程
访问
容器里不同数据段的数据
时
,
线
程
间
就不会存在
锁竞
争,从而可以有效提高并 发访问效率,
这
就是
ConcurrentHashMap
所使用的
锁
分段技
术
。首先将数据分成一段一段地存 储,然后
给
每一段数据配一把
锁
,当一个
线
程占用
锁访问
其中一个段数据的
时
候,其他段的数 据也能被其他线
程
访问
。