众所周知,HashMap是线程不安全的。但是如果需要一个线程按钮的HashMap我们需要怎么做的。
这个包装的HashMap可以满足线程安全的要求。但是,他在高并发的环境中性能表现的不好,无论是对Map的读取或者写入,都需要获得munex的锁,这会导致其他的的线程进入等待的状态。如果并发级别不高,一般也够用。但是在高并发的环境中,我们必须寻求新的解决方案。
一个更加专业的HashMap就是ConcurrentHashMap,他专门为并发进行了优化。
其中一个可行的办法就是Collections.synchronizedMap。如下代码就是线程安全的HashMap
public static Map m = Collections.synchronizedMap(new HashMap<>());
说白了,就是给HashMap加锁,jdk参考代码如下
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
return new SynchronizedMap<>(m);
}
/**
* @serial include
*/
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;
}
}
这个包装的HashMap可以满足线程安全的要求。但是,他在高并发的环境中性能表现的不好,无论是对Map的读取或者写入,都需要获得munex的锁,这会导致其他的的线程进入等待的状态。如果并发级别不高,一般也够用。但是在高并发的环境中,我们必须寻求新的解决方案。
一个更加专业的HashMap就是ConcurrentHashMap,他专门为并发进行了优化。
有关ConcurrentHashMap的实现细节,可以参考下面锁的优化。