在平时开发中,我们经常采用HashMap来作为本地缓存的一种实现方式,将一些如系统变量等数据量比较少的参数保存在HashMap中,并将其作为单例类的一个属性.在系统运行中,使用到这些缓存数据,都可以直接从该单例中获取该属性集合.但是,最近发现,HashMap并不是线程安全的,如果你的单例类没有做代码同步或对象锁的控制,就可能出现异常. 首先看下在多线程的访问下,非现场安全的HashMap的表现如何,在网上看了一些资料,自己也做了一下测试:  1public class MainClass {  …
转载:https://blog.csdn.net/qq_31493821/article/details/78855069 HashMap为什么线程不安全 导致HashMap线程不安全的原因可能有两种: 1.当多个线程同时使用put方法添加元素的时候,正巧存在两个put的key发生了碰撞(根据hash值计算的bucket一样),那么根据HashMap的存储原理,这两个key会添加多数组的同一个位置,这样一定会导致其中一个线程put的数据被覆盖丢失 2.当多个线程同时检测到元素个数超过哈希表的si…
Java 非线程安全的HashMap如何在多线程中使用 HashMap 是非线程安全的.在多线程条件下,容易导致死循环,具体表现为CPU使用率100%.因此多线程环境下保证 HashMap 的线程安全性,主要有如下几种方法: 使用 java.util.Hashtable 类,此类是线程安全的. 使用 java.util.concurrent.ConcurrentHashMap,此类是线程安全的. 使用 java.util.Collections.synchronizedMap() 方法包装 Ha…
一直以来都知道HashMap是线程不安全的,但是到底为什么线程不安全,在多线程操作情况下什么时候线程不安全? 让我们先来了解一下HashMap的底层存储结构,HashMap底层是一个Entry数组,一旦发生Hash冲突的的时候,HashMap采用拉链法解决碰撞冲突,Entry内部的变量: final Object key; Object value; Entry next; int hash; 通过Entry内部的next变量可以知道使用的是链表,这时候我们可以知道,如果多个线程,在某一时刻同时…
我们都知道.HashMap是非线程安全的(非同步的).那么怎么才能让HashMap变成线程安全的呢? 我认为主要可以通过以下三种方法来实现: 1.替换成Hashtable,Hashtable通过对整个表上锁实现线程安全,因此效率比较低 2.使用Collections类的synchronizedMap方法包装一下.方法如下: public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)  返回由指定映射支持的同步(线程安…
我们在学习 HashMap 的时候,都知道 HashMap 是非线程安全的,同时我们知道 HashTable 是线程安全的,因为里面的方法使用了 synchronized 进行同步. 但是 HashMap 为什么是非线程安全的呢?难道仅仅就是因为内部的方法没有 synchronized 关键字修饰吗?这篇文章主要来分析一下原因. 我们知道 HashMap 底层是一个 Entry 数组,当发生 hash 冲突的时候,HashMap 是采用链表的方式来解决的,在对应的数组位置存放链表的头结点.对链表…
1. HashMap 的线程不安全性的体现: 主要是下面两方面: (1)多线程环境下,多个线程同时resize()时候,容易产生死锁现象.即:resize死循环 (2)如果在使用迭代器的过程中有其他线程修改了map,那么将抛出ConcurrentModificationException,即:fail-fast策略 2. resize死循环: (1)为什么会出现resize死循环? 在单线程情况下,只有一个线程对HashMap的数据结构进行操作,是不可能产生闭合的回路的.那就只有在多线程并发的情…
HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型.HashMap 继承自 AbstractMap 是基于哈希表的 Map 接口的实现,以 Key-Value 的形式存在,即存储的对象是 Entry (同时包含了 Key 和 Value)   本文所有源码都是基于JDK1.8的,不同版本的代码差异可以自行查阅官方文档. HashMap源码(JDK1.8): public class HashMap<K,V> extends AbstractMap<K,V>…
一.一般模式下线程安全的HashMap 默认情况常用的HashMap都是线程不安全的,在多线程的环境下使用,常常会造成不可预知的,莫名其妙的错误.那么,我们如何实现一个线程安全的HashMap呢?其中一个可行的方式是使用Collectons.synchronizedMap() 方法来包装我们的HashMap.如下: Map<String, String> map = Collections.synchronizedMap(new HashMap<String,String>());…
hashMap是非线程安全的,表现在两种情况下: 1 扩容: t1线程对map进行扩容,此时t2线程来读取数据,原本要读取位置为2的元素,扩容后此元素位置未必是2,则出现读取错误数据. 2 hash碰撞 两个线程添加元素发生hash碰撞,都要将此元素添加到链表的头部,则会发生数据被覆盖. 详情: HashMap底层是一个Node数组,一旦发生Hash冲突的的时候,HashMap采用拉链法解决碰撞冲突,Node结构: /** * Basic hash bin node, used for most…