四种线程安全的 hashmap

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。

解决:

  1. 可以通过压缩容器中的元素的方法来减少大对象的消耗,如元素全是10进制的数字,可以考虑将其压缩成32进制或者64进制.
  2. 使用其他的并发容器,如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表。

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值