四种线程安全的 hashmap

本文对比了Hashtable、Collections.synchronizedMap、CopyOnWriteMap和ConcurrentHashMap四种并发容器的性能与适用场景,详细解析了CopyOnWriteMap的实现原理,以及ConcurrentHashMap的锁分段技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

达升笑讲故事 2019-06-03 09:08:25

1. hashtable

采用synchronized方法上加锁,使用阻塞同步,效率低。

2. collections.synchronizedMap(map)

也是采用synchronized方法上加锁,使用阻塞同步,效率低。

3.CopyOnWriteMap (读写分离思想)

(java本身并没有提供CopyOnWriteMap,但是我们可以自己实现一个,代码见下)

采用 写时复制 的操作

写时复制:

当对容器进行增加,删除,修改操作时,不是直接操作容器,而是先将当前容器copy,复制出一个新的容器,再对新容器进行操作,操作完成后再将指针指向这个新容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读(CopyOnWriteArrayList底层使用数组实现,而该数组是被volatile修饰),而不用对其进行加锁,当然写的时候是需要加锁的(这里采用了lock加锁),否则可能copy出了N个副本。

优点:写时不用加锁,即查询不加锁,在查询多,增删改少的情况下适合用。

缺点(问题):内存占用和数据一致性

1.内存占用

因为CopyOnWrite的写时复制机制,所有在进行写操作的时候,内存里会同时驻扎两个对象的内存,旧的对象和新的对象。如果这些对象占用的内存比较大,就有可能造成频繁的yong GC和full GC。

解决:

可以通过压缩容器中的元素的方法来减少大对象的消耗,如元素全是10进制的数字,可以考虑将其压缩成32进制或者64进制.

使用其他的并发容器,如ConcurrentHashMap。

2.数据一致性

CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性(因为在对新容器进行写操作时,其它线程可能也在操作原容器)。所有如果你希望写入的数据,马上能读到,CopyOnWrite可能无法满足要求。

CopyOnWriteMap的实现代码:

import java.util.Collection;

import java.util.Map;

import java.util.Set;

public class CopyOnWriteMap<K, V> implements Map<K, V>, Cloneable {

private volatile Map<K, V> internalMap;

public CopyOnWriteMap() {

internalMap = new HashMap<K, V>();

}

public V put(K key, V value) {

synchronized (this) {

Map<K, V> newMap = new HashMap<K, V>(internalMap);

V val = newMap.put(key, value);

internalMap = newMap;

return val;

}

}

public V get(Object key) {

return internalMap.get(key);

}

public void putAll(Map<? extends K, ? extends V> newData) {

synchronized (this) {

Map<K, V> newMap = new HashMap<K, V>(internalMap);

newMap.putAll(newData);

internalMap = newMap;

}

}

}

4.ConcurrentHashMap

采用锁分段技术,减小锁的粒度,效率高

ConcurrentHashMap中是一次锁住一个桶。

ConcurrentHashMap默认将hash表分为16个桶,诸如get,put,remove等常用操作只锁当前需要用到的桶。

这样,原来只能一个线程进入,现在却能同时有16个写线程执行,并发性能的提升是显而易见的。上面说到的16个线程指的是写线程,而读操作大部分时候都不需要用到锁。只有在size等操作时才需要锁住整个hash表。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值