Hashtable VS SychronizedMap VS ConcurrentHashMap

       JAVA Collection 是Java API的核心。所以使用java本身的集合比如HashMap/ArrayList或者LinkedList来访问,存储和处理java应用中的数据是非常找重要的。比如,我们经常使用HashMap来在MVC框架层内传输数据。

 

面试官可能会问你”HashMap是一个线程安全的类吗?”

 

HashMap

      线HashMap程并不安全,如果多线程访问同一个HashMap对象,并试图通过put和remove方法来修改HashMap的结构,可能会导致HashMap的状态不同步。

 

       为了在多线程环境中使用HashMap,你必须实现一些同步代码块或者使用外部的锁Lock机制。但是如果使用不当,这样又很有可能出现的错误和死锁的情况。

 

      总之,并不建议在多线程环境下使用HashMap,可以使用现场安全的Hashtable,Collection.SynchronizedMap,或者ConcurrentHashMap。同样线程安全的情况下,ConcurrentHashMap却有着比其它两个更加优秀的查询和增删性能。

 

Hashtable

 

       Hashtable使用synchronized关键字实现线程安全,每次只能由一个线程读或写。换句话说,整个Hashtable对象都被同步起来了。因此,它的性能很低,所以在多线程架构下我们也无法利用到它的优势。

 

需要注意的一点是,Hashtable不允许存在null的key或value,而HashMap则允许。

 

Collections.SynchronizedMap

 

       SynchronizedMap是java.util.Collections的一个静态内部类。它根Hashtable很像,也是整个Map对象都需要同步。这是Collection的辅助类,jdk1.5引入。

 

可以使用Collections.SynchronizedMap(Map map)方法,可以把线程不安全的Map实现类转换为线程安全的类。

 

比如

 

 

输出

 

 

       Collections.SynchronizedMap内部使用synchronized关键字把Map接口的所有方法包裹了起来。来看它内部的put方法和remove方法

 

 

类似HashMap,被同步过的HashMap不允许存储null key和null values,其它属性与原有collection并无差别。

 

另外,SynchronizedSortMap可以把线程不安全的TreeMap和SortedMap实现类转换为线程安全的。

 

ConcurrentHashMap

      Hashtable和SynchronizedMap都需要在整个Map对象上加锁才能实现线程安全,每次只能一个线程访问Map对象,性能可想而见。

 

       所以在JDK 1.5中的引入了并发包,其中的ConcurrentHashMap就是为了克服这一问题而生的,同时引入同步类还有CountDownLatch,CyclicBarrier,CopyOnWriteArrayList,BlockingQueue等等。

 

 

ConcurrentHashMap中可以有多个线程同步读和写,而且还能保证线程安全。我们来看下图:

 

 

         ConcurrentHashMap把Map对象切分成了不同的segments(段),在每个段上加锁。默认可以16个线程同步访问,默认并发级别也是16,但是我们可以在构造器中手动配置并发级别。

 

 

我们来看下面的一些常见问题:

  1. ConcurrentHashMap允许多个线程写同一个segment吗?

不允许,写(put())操作的时候会加锁,一个segment在同一时间只能由一个线程写。

 

  1. 不同segment允许两个线程写吗?

允许,允许两个线程同一时间在不同segment上写操作。

 

  1. 同一个segment允许多个线程读吗?

允许,读不用锁,随意读。

 

  1. 如果一个线程在写入一个segment,那么另一个线程允许读这个segment吗?

允许,但是只会获得最新值。

 

另外,ConcurrentHashMap不允许存储null key和null value

 

总结

 

1。HashMap线程不安全

2。SynchronizedMap使用synchronized锁包裹了Map对象。

3。Hashtable和ConcurrentHashMap不允许存储null key和 null value,然而SynchronizedMap允许。

4。Hashtable和SynchronizedMap变的很大时,因为实在整个对象上加了锁,它的性能会急剧下降,而ConcurrentHashMap即使整个表变的很大,分段锁的存在则提高了ConcurrentHashMap在多线程环境下的表现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值