谈谈你理解的 HashMap,讲讲其中的 get put 过程。 1.8 做了什么优化? 是线程安全的嘛? 不安全会导致哪些问题? 如何解决?有没有线程安全的并发容器? ConcurrentHashMap 是如何实现的? 1.7、1.8 实现有何不同?为什么这么做?
时间: 2024-05-25 18:13:40 浏览: 105
HashMap是一种键值对存储的数据结构。它基于哈希表实现,通过对key的哈希值进行计算来确定key在内存中的存储位置,从而实现快速的查找、插入和删除操作。
当我们向HashMap中添加一个键值对时,首先会根据key的哈希值计算出在数组中的位置,然后判断该位置是否已经有元素,如果没有,则直接将键值对放在该位置;如果有,则遍历该位置上的链表或红黑树,找到与要插入的key相同的节点,如果找到了,则更新该节点的值,否则在链表或红黑树的末尾添加一个新节点。
当我们从HashMap中获取一个键对应的值时,首先会根据key的哈希值计算出在数组中的位置,然后遍历该位置上的链表或红黑树,找到与要查找的key相同的节点,如果找到了,则返回该节点的值,否则返回null。
在1.8版本中,HashMap做了很多优化,其中包括:
1.使用红黑树代替链表:当某个桶中的链表长度超过阈值(默认为8)时,会将链表转化为红黑树,从而提高查找效率。
2.引入了树化阈值和树退化阈值:当桶中链表长度与树节点数在这两个阈值之间时,会根据桶中元素的数量决定是将红黑树转化为链表还是将链表转化为红黑树。
3.使用数组+链表+红黑树的存储结构:在1.8版本中,HashMap使用了数组+链表+红黑树的存储结构,不仅提高了查找效率,还减少了内存的占用。
HashMap是非线程安全的,如果多个线程同时对同一个HashMap进行修改,可能会导致数据不一致的情况。为了解决这个问题,可以使用线程安全的并发容器,如ConcurrentHashMap。
ConcurrentHashMap实现了分段锁的机制,将整个HashMap分成了多个Segment,每个Segment上都有一个独立的锁,只有获取锁的线程才能对该Segment进行修改。这样就可以在不影响其他Segment的情况下,让多个线程同时对不同的Segment进行操作,从而提高了并发性能。
在1.7版本中,ConcurrentHashMap使用了分段锁机制,但是所有Segment上的锁都是独占锁,无法支持读写并发。在1.8版本中,ConcurrentHashMap使用了读写锁机制,将Segment中的锁分为了读锁和写锁,从而支持了读写并发操作,提高了并发性能。
阅读全文