当前位置: 首页>后端>正文

Map映射集合

Map映射集合

学习其子类

HashMap:

HashMap是一个以键值对方式存储数据的集合,键必须唯一,不能保证存储时的顺序。但可以存储空的键和值(key,value),这就和Hashtable的一点区别,HashMap和Hashtable相似,只是Hashtable内还加了同步方法,所以是线程安全的,HashMap不是线程安全的。

扩容机制:HashMap的初始容量为16,当数据达到了容量的四分之三的时候也就是0.75时,就会触发扩容机制,也就是16+16*0.75=28。当然也可以手动去初始化容量。

HashMap的底层结构是一个数组加单链表。

Hashtable:

Hashtable是一个线程安全的结合,里面的方法都是被synchronized所修饰。自然把HashMap线程要安全,在多线程操作情况下,只允许一个线程去对Hashtable进行操作,等这个线程运行完释放锁之后,其他线程才可以去获取这个同步锁操作Hashtable.

HashMap和Hashtable相比较而言,HashMap线程不安全它的效率较快,Hashtable线程安全但是较慢,我们可以把HashMap维护到线程安全的情况。用Collections.synchronizedMap(new HashMap<>());这样也就给HashMap加上了一个同步锁。如果要使用一个线程安全的Map集合可以使用并发包下的ConcurrentHashMap(),在高并发的情况下有很高的性能。

扩容机制:hashtable的初始容量是11,当数据的容量(可以称为阈值)快要到达初始容量的0.75的时候就会开始自动扩容,不过他的扩容方式和hashMap的不同,是11*2+1=23。由于Hahshtable是线程安全,锁住的是整个Entry数组,高并发的情况下性能会变差。这个时候我们可以考虑使用ConcurrentHashMap来提高并发时候的效率。ConcurrentHashMap是一个高吞吐量而且线程安全的HashMap。

LinkedHashMap:

LinkedHashMap继承了HashMap,所以HashMap的特性它都有,然后它自己也加人了一个双向链表,所以在存储的顺序上是有序的而且不会乱掉,一直会保持这原有的插入的顺序。(这里我们写功能的时候用到了打印的条形码,必须唯一而且是有顺序的,不用排序,只要保持开始存进来的顺序即可,就用到了LinkedHashMap,因为我们当时还用了Hashtable这个对象,发现它是无序的,这就把原来的条形码的打印顺序都打乱掉了,所以换了一个有顺序且唯一的LinkedHashMap。就是有一点在多线程高并发的情况下可能还是会出现重复的键问题。比如我和其他人一起操作打印功能,在这期间我可能把一个键1234存到LinkedHashMap里面去了,然后另一个人也可能把这个1234存进去,然后再提交打印的时候会就生成重复的条形码存入到数据库当中,这个时候就会提示报错,出现重复主键问题。所以我现在想可将这LinkedHashMap维护成线程安全的,也就是Collections.synchronizedMap(new LinkedHashMap<>()))

TreeMap:

TreeMap是红黑树实现的,会自动排好序,红黑是是自平衡二叉树的一种。

探究一下Hashtable和ConcurrentHashMap的区别:

这两个集合都是线程安全的,但是相比较而言Hashtable效率比较低,尽管它线程安全,但是办事效率不高。

ConcurrentHashMap是一个支持多线程高并发的情况下还能保持线程安全高效率的集合。那么它是怎么做到的呢?深入探究一下

Hashtabl底层是数组+链表,很像HashMap它的每个方法几乎都有synchronized修饰因此它是线程安全的,固然的效率不高。同时它不能存储空键和空值,所以在Hashtable中获取的数据不用判断非空,因为它里面必须有值。在执行的HashMap锁定整张hash表,只能一个进程锁定该张表,其他必须等它执行完释放这把锁之后才可以操作它。

ConcurrentHashMap是一个非常优秀的集合框架,底层是分段锁+链表(JDK1.8之前)是线程安全的,同时它的效率还提升了N倍,默认是16倍提升。ConcurrentHashMap允许多个线程同时修改操作并发进行。是因为它的关键操作是在于锁分类技术。每个锁之间都可以独立进行维护,默认是运行16个线程同时访问。

扩容机制:段内扩容,段内的元素要超过该段的Entry数组的75%就会自动扩容,只对这一段进行扩容,而不会对整个ConcurrentHashMap进行扩容。

Hashtable和HashMap都实现了Map接口,但是Hashtable是基于Dictionaty抽象类的。而JDK1.5之后出现了ConcurrentHashMap,它的能够在高并发的情况下保证线程安全,它可以替换掉Hashtable,比Hashtable更具有可扩展性。


https://www.xamrdz.com/backend/32r1935120.html

相关文章: