HashMap为什么不安全?
HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组位置存放链表的头结点。对链表而言,新加入的节点会从头结点加入。
javadoc中关于hashmap的一段描述如下:
此实现不是同步的。如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步。(结构上的修改是指添加或删除一个或多个映射关系的任何操作;仅改变与实例已经包含的键关联的值不是结构上的修改。)这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedMap 方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射进行意外的非同步访问
比如一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:
1. 在 Items[Size] 的位置存放此元素;
2. 增大 Size 的值。
在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;
而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。
那好,现在我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。
两个原因,一个是put的时候可能导致多线程的数据不一致。另一个是扩容的时候,jdk1.8采用头插法,当两个线程同时检测到hashmap需要扩容,同时进行扩容的话可能使得链表死循环。
HashMap为什么不安全?
有两个原因 存放数据时,HashMap不是线程安全的 比如有两个线程A和B,首先A希望插入一个key-value对到HashMap中,首先计算记录所要落到的桶的索引坐标,然后获取到该桶里面的链表头结点,此时线程A的时间片用完了,而此时线程B被调度得以执行,和线程A一样执行,只不过线程B成功将记录插到了桶里面,...
HashMap为什么变成从尾部插入?
8采用的是尾插入法。 HashMap在jdk1.7中采用头插入法,在扩容时会改变链表中元素原本的顺序,以至于在并发场景下导致链表成环的问题。而在jdk1.8中采用尾插入法,在扩容时会保持链表元素原本的顺序,就不会出现 链表成环 的问题了。参考: HashMap之元素插入 , HashMap为何从头插入变成尾插入 ...
[笔记]为什么hashmap查询速度快? 如何理解hashmap的散列?
那么 hashmap 是通过hashcode进行散列,hashcode 是如何分组不得而知,但是原理也是一样,尽可能的平均分布 均匀 ,比如1万个数据如果 只有10个组,或者说 100个组里面数据全部在 第一个组,这效率还是一样 速度比简单粗暴的list 更慢了,为什么速度更慢了?比如1万个数据 分了100个组,但是...
hashmap为什么是线程不安全的
因为在jdk1.7中,在多线程环境下,扩容时会造成环形链或数据丢失、死循环。因为是链表结构,那么就很容易形成闭合的链路,这样在循环的时候只要有线程对这个HashMap进行get操作就会产生死循环。但是,我好奇的是,这种闭合的链路是如何形成的呢。在单线程情况下,只有一个线程对HashMap的数据结构进行操作...
hashmap算法复杂度为什么为O(1)
因为hashMap内部维护了一个Entry数组,hashcode即数组下标,根据key.hashcode()即可在数组中get到Entry对象,即O(1)。当然,这是理想情况。倘若数据量大,则可能发生hash碰撞,即一个hashcode可能对应多个key,这时候这个Entry数组中的元素就不是Entry了,而是一个Entry链表。调用map.get(key)的时候,遇到...
为什么hashmap线程不安全?
设计hashmap,与hashtable 的原因:已知线程同步需要消耗一定的时间来达到数据的一至性,hashmap中所有函数 没有去检查在其它线程中的使用情况下就进行操作了。所以导致了数据 操作结果不理想,但速度较快,适用使用在函数内部作为局部变量,hashtable 则所有函数声明了线程同步的 synchronized ,所以hashtable...
HashMap为什么存取效率那么高
1、出于并发性的考虑,同步保证多个进程不会同时修改一个对象,可以说,它是一种“锁”。 2、轻量这个词多用于微软的ActiveX,也许用在这并不恰当,但我只是想表达效率高、存储消耗小的意思。 3、在多个进程同时访问HashMap,并且其中一个进程修改...
为什么HashMap使用红黑树而不使用AVL树?
AVL也是logn;红黑树舍去了严格的平衡,使其插入,删除,查找的效率稳定在O(logn)反观AVL树,查找没问题O(logn),但是为了保证高度平衡,动态插入和删除的代价也随之增加,综合效率肯定达不到O(logn)所以在进行大量插入,删除操作时,红黑树更优一些 Hashmap用到数据结构有 数组,链表,红黑树 在没有...
hashmap 为什么线程不安全
有2种办法让HashMap线程安全,分别如下:方法一:通过Collections.synchronizedMap()返回一个新的Map,这个新的map就是线程安全的。 这个要求大家习惯基于接口编程,因为返回的并不是HashMap,而是一个Map的实现。方法二:重新改写了HashMap,具体的可以查看java.util.concurrent.ConcurrentHashMap. 这个方法比...
为什么面试要问hashmap 的原理?
“HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。从这里开始,真正的困惑开始了,一些面试者会回答因为hashcode相同,所以两个对象是相等的,HashMap将会抛出异常,或者不会存储它们。然后面试官可能会提醒他们有equals()和hashCode两个方法,...
汪沈中风: HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组位置存放链表的头结点.对链表而言,新加入的节点会从头结点加入.javadoc中关于hashmap的一段描述如下:此实现不是同步的....
乌海市18527881458: 为什么hashmap线程不安全 - ?
汪沈中风: 一直以来只是知道HashMap是线程不安全的,但是到底HashMap为什么线程不安全,多线程并发的时候在什么情况下可能出现问题?HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组...
乌海市18527881458: hashmap 为什么线程不安全 - ?
汪沈中风: 有2种办法让HashMap线程安全,分别如下:方法一:通过Collections.synchronizedMap()返回一个新的Map,这个新的map就是线程安全的. 这个要求大家习惯基于接口编程,因为返回的并不是HashMap,而是一个Map的实现.方法二:重新改写了HashMap,具体的可以查看java.util.concurrent.ConcurrentHashMap. 这个方法比方法一有了很大的改进.
乌海市18527881458: 如何线程安全的使用HashMap - ?
汪沈中风: 在周二面试时,一面的面试官有问到HashMap是否是线程安全的,如何在线程安全的前提下使用HashMap,其实也就是HashMap,Hashtable,ConcurrentHashMap和synchronized Map的原理和区别.当时有些紧张只是简单说了下HashMap不是线...
乌海市18527881458: Java中,map分为哪些种类? - ?
汪沈中风: Map有:HashMap、TreeMap、Hashtable.1、HashMap:线程不安全,键、值不允许为null,并且没顺序.2、Hashtable:线程安全,键、值允许为null,并且没顺序.3、TreeMap:线程不安全、键、值不允许为null,并且没顺序. 备注:当前用的最多的是HashMap,因为线性不安全,也就是说读取和存储效率要更高一些.
乌海市18527881458: hashmap多线程为什么造成死循环 - ?
汪沈中风: 一直以来只是知道HashMap是线程不安全的,但是到底HashMap为什么线程不安全,多线程并发的时候在什么情况下可能出现问题? HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组位置存放链表的头
乌海市18527881458: hashmap是线程安全还是不安全的 - ?
汪沈中风: String, Interger这样的wrapper类作为HashMap的键是再适合不过了,而且String最为常用.因为String是不可变的,也是final的,而且已经重写了equals()和hashCode()方法了.其他的wrapper类也有这个特点.不可变性是必要的,因为为了...
乌海市18527881458: javaAPI文档中写hashmap“此实现不是同步的”线程不安全而hashtable“此实现是同步的”线程安全?
汪沈中风: 意思是hashmap在多个线程同时操作时,结果会不可预料.而hashtable不会出现这个问题.具体原理你可以多了解一下多线程的东西.
乌海市18527881458: Hashtable与HashMap有什么区别? - ?
汪沈中风: hashmap 线程不安全 允许有null的键和值 效率高一点、 方法外同步 有containsvalue和containsKey方法 HashMap 是Java1.2 引进的Map interface 的一个实现 HashMap是Hashtable的轻量级实现 hashtable 线程安全 不允许有null的键和值 效率稍低、 方法是是Synchronize的 有contains方法方法 、Hashtable 继承于Dictionary 类 Hashtable 比HashMap 要旧
乌海市18527881458: java hashset为什么线程不安全 - ?
汪沈中风: 安全和效率的zd问题 table虽然线程安全, 但是效率底 我们很多时候不会考虑到多线程的问题, 所以正确的做法就是如果需要专属, 使用效率高的hashmap而同时自己去同步, 而不是为了少写点编码, 而不管需要不需要同步都去使用效率低的hashtable