轻松理解-中高级java开发必知必会 之 三兄弟 HashMap ,HashTable ,ConcurrentHashMap

这段时间比较闲,可以把之前理解整理出来的文档不断地挪到这上面来

言归正传:

在日常工作中 你会选择hashMap 还是HashTable 还是ConcurrentHashMap

让他们先来自我介绍吧:

首先HashMap和HashTable都实现了Map接口,但是HashTable是基于Dictionary抽象类的

HashTable底层 是数组加链表实现,在线程上是安全的,但是在多线程中却不去运用因为,为了实现线程安全将整个HashTable锁住,固然效率不高。

扩容:其初始size是11 触发扩容后的size是oldsize*2+1

特点:但是他有一个特点就是其key和value都可以为空,所以到底要干嘛?

HashMap在实际开发中用的非常多,是因为其put操作效率比较高,但是从线程上来说HashMap是不安全的。

扩容:其初始size是16 扩容后 是oldsize*2 就是在添加第17个的时候可以触发扩容,但是也不一定,要看现在的hash碰撞情况,当16个每一个坑占一个hash效率是最高的时候,比如存入16个值还可以存入10个值,我们来算一下,负载因子0.75,我们用16*0.75=12 当前面11个值全部hash碰撞,未超过阈值12,且只占了一个位置,那可以得出11+15=26,所以在添加第27个的时候开始扩容,这里有点绕可以了解下,只要记住一次扩容是原来的两倍即可

特点:key和vlue都可以为空

ConcurrentHashMap

底层还是数组加链表的形式,从线程上来讲是安全的,多个线程可以同时读和写,而且效率比较高,因为在ConcurrentHashMap的内部是将其分段处理,Map分为N个Segment。

扩容:扩容的操作是在段内实施的,和HashMap同理;

特点:

1.有些方法确是需要跨段的如size()方法containsValue()在方法执行的时候,按顺序锁定所有的段,操作完成后再去释放所有的段。

2.在ConcurrentHashMap的读 操作时候,是不对分段进行加锁的,因为其value变量采用volatile(可见性)可以保证当前读取的最新的值

总结:在线程中HashMap不安全;HashTable和ConcurrentHashMap是线程安全的,但是由于ConcurrentHashMap分段加锁的特点,在效率上让HashTable相形见绌,所以ConcurrentHashMap更像是高配版的HashTable。

扩容上ConcurrentHashMap分段扩容和HashMap同理,Hash则是oldsize+1

猜你喜欢

转载自blog.csdn.net/qq_34077993/article/details/83653039