营销型网站建设一般多少钱,提供网站建设小程序制作,wordpress安装无法链接数据库,微信小程序购物商城源码转载自 如何线程安全的使用HashMap 在周二面试时#xff0c;一面的面试官有问到 HashMap 是否是线程安全的#xff0c;如何在线程安全的前提下使用 HashMap,其实也就是 HashMap#xff0c;Hashtable#xff0c;ConcurrentHashMap 和 synchronized Map 的原理和区别。当时有…转载自 如何线程安全的使用HashMap 在周二面试时一面的面试官有问到 HashMap 是否是线程安全的如何在线程安全的前提下使用 HashMap,其实也就是 HashMapHashtableConcurrentHashMap 和 synchronized Map 的原理和区别。当时有些紧张只是简单说了下HashMap不是线程安全的Hashtable 线程安全但效率低因为是 Hashtable 是使用 synchronized 的所有线程竞争同一把锁而 ConcurrentHashMap 不仅线程安全而且效率高因为它包含一个 segment 数组将数据分段存储给每一段数据配一把锁也就是所谓的锁分段技术。当时忘记了 synchronized Map 和解释一下 HashMap 为什么线程不安全。面试结束后问了下面试官哪里有些不足面试官说上面这个问题的回答算过关但可以在深入一些或者自己动手尝试一下。so~~~虽然拿到了 offer但还是再整理一下不能得过且过啊。
为什么HashMap是线程不安全的
总说 HashMap 是线程不安全的不安全的不安全的那么到底为什么它是线程不安全的呢要回答这个问题就要先来简单了解一下 HashMap 源码中的使用的存储结构(这里引用的是 Java 8 的源码与7是不一样的)和它的扩容机制。
HashMap的内部存储结构
下面是 HashMap 使用的存储结构:
transient NodeK,V[] table;
static class NodeK,V implements Map.EntryK,V {final int hash;final K key;V value;NodeK,V next;
} 可以看到 HashMap 内部存储使用了一个 Node 数组(默认大小是16)而 Node 类包含一个类型为 Node 的 next 的变量也就是相当于一个链表所有根据 hash 值计算的 bucket 一样的 key 会存储到同一个链表里(即产生了冲突)大概就是下面图的样子(顺便推荐个在线画图的网站Creately)。HashMap内部存储结果 需要注意的是在 Java 8 中如果 hash 值相同的 key 数量大于指定值(默认是8)时使用平衡树来代替链表这会将get()方法的性能从O(n)提高到O(logn)。具体的可以看我的另一篇博客Java 8中HashMap和LinkedHashMap如何解决冲突。 HashMap的自动扩容机制
HashMap 内部的 Node 数组默认的大小是16假设有100万个元素那么最好的情况下每个 hash 桶里都有62500个元素