简述:如何解决HashMap线程不安全的问题?
Posted zhangjin1120
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简述:如何解决HashMap线程不安全的问题?相关的知识,希望对你有一定的参考价值。
jdk1.8中HashMap为什么线程不安全?
会出现数据覆盖。
JDK1.7和JDK1.8中HashMap为什么是线程不安全的?
怎么解决HashMap线程不安全的问题?
1.使用HashTable替代HashMap
HashTable的put操作,有
synchronized
关键字修饰。
2.使用
Map map = Collections.synchronizedMap(new HashMap());
这个方法实际上返回了一个
SynchronizedMap
。
SynchronizedMap 实现线程安全的方法也是比较简单的,所有方法都是先对锁对象 mutex 上锁,然后再直接调用 Map 类型成员变量 m 的相关方法。这样一来,线程在执行方法时,只有先获得了 mutex 的锁才能对 m 进行操作。因此,跟 Hashtable 一样,在同一个时间点,只能有一个线程对 SynchronizedMap 对象进行操作,虽然保证了线程安全,却导致了性能低下。这么看来,连 Hashtable 都被弃用了,那性能同样低下的 SynchronizedMap 还有什么存在的必要呢?别忘了,后者的构造方法需要传入一个 Map 类型的参数,也就是说它可以将非线程安全的 Map 转化为线程安全的 Map。
上面这段话出自: Hashtable,SynchronizedMap和ConcurrentHashMap线程安全对比
看看这个类的源码:
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
return new SynchronizedMap<>(m);
}
private static class SynchronizedMap<K,V>
implements Map<K,V>, Serializable {
private static final long serialVersionUID = 1978198479659022715L;
private final Map<K,V> m; // Backing Map
final Object mutex; // Object on which to synchronize
SynchronizedMap(Map<K,V> m) {
this.m = Objects.requireNonNull(m);
mutex = this;
}
...
}
//SynchronizedMap的put方法,实际调用的还是HashMap自己的put方法
public V put(K key, V value) {
synchronized (mutex) {return m.put(key, value);}
}
3.使用ConcurrentHashMap
jdk1.8中ConcurrentHashMap通过 CAS+synchronized实现线程安全。
Java并发——ConcurrentHashMap(JDK 1.8)
以上是关于简述:如何解决HashMap线程不安全的问题?的主要内容,如果未能解决你的问题,请参考以下文章
ArrayListHashSet和HashMap线程不安全的解决办法