关于hashmap和hashtable的区别,及如何使hashmap变得线程安全?(除了synchronized)---concurrentHashmap

我们都知道hashmap是线程不安全的,而效率也比较高,他允许我们存入null键及null值;

而 hashtable 是线程安全的,其效率比较低,不允许我们存入null键和null值;

除了非同步及允许使用null值,hashmap与hashtable基本相同;

那么为什么hashtable是线程安全的呢?我们可以翻看一下:


例如:put 方法,hashtable中几乎所有的方法都是被synchronized 修饰的;以保证其安全性;

synchronized 可以修饰静态方法(锁对象为本类的字节码文件对象)、修饰普通方法(锁对象为this,即谁调用了它)、修饰某段代码(锁对象为任意对象);

再来说hashmap,它的get put 方法没有加同步,那么意味着,如果2个线程同时put了两个相同的key时,这2个key会被放到数组中的同一位置,(hashmap 中的key是

用数组来存储的),就会导致其中一个线程put的数据被覆盖;另外:hashmap并发执行put 操作时会引起死循环(其实是发生在数组扩容时,hashmap 中的node链表

形成环形数据结构)。

所以在api中给出了这样的方法保证hashmap的安全:

扫描二维码关注公众号,回复: 4071556 查看本文章
 Map m = Collections.synchronizedMap(new HashMap(...));
 
 
当然还有另外一种方法就是:使用ConcurrentHashmap:这个类遵守与Hashtable相同的功能规范,即支持Hashtable的所有功能(注意:它 允许将 null 用作键或值);
除此之外还支持多线程对map 的读操作,在执行写操作时,CHM只锁住部分的Map,同时支持16个进程进行写操作,读操作不受限制;
原因在于
ConcurrentHashmap引用了锁分割,将map分割为16部分(默认初始容量为16),由不同的锁控制;
不过,尽管所有操作都是线程安全的,获取操作 必锁定,支持某种以所有访问的方式锁定整个表,CHM不会锁住整个Map
 
 
ConcurrentHashmap 要比
Map m = Collections.synchronizedMap(new HashMap(...)); 方法  和hashtable 效率相对较高(应用场景:读取多于写入);

 
 

猜你喜欢

转载自blog.csdn.net/q18810146167/article/details/70285782