- 结论
- 为啥不用hashMap
- Hashtable 和 concurrentHashMap 区别
- Hashmap
- HashTable
请切记,并发环境下不要使用hashmap。原因是jdk1.7之前使用hashmap进行扩容时,会造成死循环。虽然在1.8修复了这个问题,但是高并发情况下依然会导致数据不准确的问题(查看hash源码会发现,没有使用锁,因此本质上hashmap就是线程不安全的)
Hashtable 和 concurrentHashMap 区别 Hashmap我们先看下jdk1.8中concurrentHashMap 的实现
// An highlighted block
public V put(K key, V value) {
return putVal(key, value, false);
}
final V putVal(K key, V value, boolean onlyIfAbsent) {
//省略逻辑
V oldVal = null;
synchronized (f)
}
public V remove(Object key) {
return replaceNode(key, null, null);
}
final V replaceNode(Object key, V value, Object cv) {
//省略逻辑
synchronized (f)
}
从源码可以看出concurrentHashMap中的remove(),clear(),put()方法都使用了锁,实现了细粒度的锁,减少了竞争锁的开销(可能产生锁竞争的地方减少了)。
但是!!!!
我们看下他的get方法,没有加锁。
// An highlighted block
public V get(Object key) {
Node[] tab; Node e, p; int n, eh; K ek;
int h = spread(key.hashCode());
if ((tab = table) != null && (n = tab.length) > 0 &&
(e = tabAt(tab, (n - 1) & h)) != null) {
if ((eh = e.hash) == h) {
if ((ek = e.key) == key || (ek != null && key.equals(ek)))
return e.val;
}
else if (eh < 0)
return (p = e.find(h, key)) != null ? p.val : null;
while ((e = e.next) != null) {
if (e.hash == h &&
((ek = e.key) == key || (ek != null && key.equals(ek))))
return e.val;
}
}
return null;
}
同理他的size方法也没有加锁.
这里可以看出容易产生读不一致的问题,即两次读可能结果不一样。因此,如果对读有较强的一致性要求则明显不适应
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry entry = (Entry)tab[index];
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
addEntry(hash, key, value, index);
return null;
}
hashtable 中的put方法等都是这样简单粗暴的锁住整个方法,因此产生的锁竞争就更多了。但同时也保证了数据的强一致性。因此,如果对数据一致性要求高的话可以用hashtable,但是自然效率就没有concurrentHashMap高
好了,map的分享就到这里了。下期我再分享list的容器选择。
我是和弦,一名互联网枸杞人,如果文章对你有帮助,请点个赞吧!



