hashmap多线程问题总结:
1、jdk1.8前存在多线程赋值死循环问题
2、所有jdk版本存在多线程赋值丢失数据问题
代码开路(具体原因分析不赘述,网络上很多自己去找):
package com.song.javabase; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; /** * Created by feng on 2019/9/6. */ public class HashMapDemo { public static void main(String[] args){ //jdk1.8以下会引起部分线程死循环,多试几次,不是必现,jdk1.8解决了该问题 testMyThread(); //hashmap多线程hash冲突导致数据被覆盖,jdk1.8也有此问题 //testMyThread1(); //concurrenthashmap多线程解决MyThread1的问题 //testMyThread2(); } public static void testMyThread(){ for(int i = 1; i <= 10; i++){ new Thread(new MyThread(i)).start(); } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(MyThread.atomicInteger); System.out.println(MyThread.map.size()); } public static void testMyThread1(){ for(int i = 1; i <= 10; i++){ new Thread(new MyThread1(i)).start(); } try { new Thread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(MyThread1.map.size()); } public static void testMyThread2(){ for(int i = 1; i <= 10; i++){ new Thread(new MyThread2(i)).start(); } try { new Thread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(MyThread2.map.size()); } } class MyThread implements Runnable{ public static Map<Integer,Integer> map = new HashMap<Integer,Integer>(1); public static AtomicInteger atomicInteger = new AtomicInteger(0); private int id; public MyThread(int id){ this.id = id; } @Override public void run() { for(int i = 0; i < 100000; i++) { //由于atomicInteger取值和加值不在一步操作,多线程下不但有数据跳过导致丢失,还可能产生同值hash碰撞,导致resize时hashmap死循环 map.put(atomicInteger.get(), atomicInteger.get()); atomicInteger.incrementAndGet(); //即使atomicInteger取值和加值在一步操作,多线程下不会导致死循环,但是会有数据跳过导致丢失,atomic并不是万能的 //int index = atomicInteger.getAndIncrement(); //map.put(index, index); //同步代码块解决上述问题 //synchronized (atomicInteger){ //map.put(atomicInteger.get(), atomicInteger.get()); //atomicInteger.incrementAndGet(); //} } System.out.println(id + "结束"); } } class MyThread1 implements Runnable{ public static Map<Integer,Integer> map = new HashMap<Integer, Integer>(1); public int index; private int id; public MyThread1(int id){ this.id = id; this.index = (id - 1) * 10000; } @Override public void run() { int count = 0; //index分区间线程不干扰,最终hashmap的大小不够10w,说明有hash冲突导致数据被覆盖。 for(int i = 0; i < 10000; i++) { map.put(index , index); index ++; count ++; } System.out.println(id + "结束,总共" + count +"次"); } } class MyThread2 implements Runnable{ public static Map<Integer,Integer> map = new ConcurrentHashMap<Integer, Integer>(1); public int index; private int id; public MyThread2(int id){ this.id = id; this.index = (id - 1) * 10000; } @Override public void run() { int count = 0; //index分区间多线程不干扰,改成concurrentHashMap,不存在hash冲突数据被覆盖的问题 for(int i = 0; i < 10000; i++) { map.put(index , index); index ++; count ++; } System.out.println(id + "结束,总共" + count +"次"); } }
相关推荐
4. 避免在多线程环境中直接使用HashMap:如果你确定不需要在多线程环境下共享HashMap,那么可以考虑局部变量的方式,只在单个线程中使用HashMap,这样就无需担心线程安全问题。 总结起来,理解HashMap的线程不安全...
然而,对于多线程环境,HashMap并不是线程安全的,这在并发编程中可能会引发一系列问题。本篇将深入探讨HashMap的线程安全问题,并提供相关的解决方案。 首先,我们需要了解HashMap在多线程环境下可能出现的问题: ...
在Java的HashMap中,多线程并发环境下的扩容操作可能会引发死锁问题。这主要发生在JDK 1.7版本,因为其扩容机制采用了头插法。以下详细解释这个问题及其解决方案。 首先,HashMap的扩容机制是在容量达到阈值时触发...
### HashMap多线程解决方案 #### 一、引言 在多线程环境下,Java的`HashMap`类在处理并发操作时容易出现线程安全问题。本文档深入探讨了`HashMap`在多线程环境中可能遇到的安全问题,并提出了一系列可行的解决方案...
这个主题通常涉及到多线程编程和Java集合框架的基础知识。本篇文章将通过分析`HashMap`的源码以及编写一个简单的测试程序来证明这一点。 首先,我们要理解什么是线程安全。线程安全是指在多线程环境中,一个类或...
然而,`HashMap`并非线程安全,这意味着在多线程环境中直接使用`HashMap`可能会导致数据不一致、并发问题,甚至程序崩溃。本项目“hashmap-thread-test”显然是为了测试和展示这一特性。 ### Java HashMap 的特性 ...
目录 1.什么是线程安全性(what) 2.如何分辨一个类是否线程安全?(HOW) ...正确性:多个线程访问某个类,不管怎么调度这些线程,其代码中不需要额外的同步或协同(synchronized),这个类依然有正确
答:在多线程环境下,可以使用ConcurrentHashMap,它是线程安全的HashMap实现。 五、HashMap与HashSet的关系 HashSet基于HashMap实现,每个元素作为HashMap的一个键,值为null。因此,HashSet的操作性能也依赖于...
在Java编程语言中,多线程是实现并发执行任务的关键技术。这个压缩包中的内容,"Java多线程矩阵...通过对代码的阅读和分析,我们可以深入理解Java多线程在解决实际问题中的应用,同时也能掌握矩阵运算的并行化策略。
根据给定文件的信息,我们可以提炼出以下关于Java多线程程序设计的知识点: ### Java多线程基础 在Java中,多线程是通过`Thread`...掌握多线程编程不仅可以提升程序的性能,还能解决并发问题,使程序更加高效和稳定。
多线程ATM取款机模拟 在 Java 中实现多线程 ATM 取款机模拟,涉及到多个关键技术点,如线程安全、同步机制、账户管理等。本文将详细解释标题、描述、标签和部分内容中的知识点。 1. 多线程编程 多线程编程是 Java...
为了避免这种情况,开发者需要在多线程环境下使用线程安全的数据结构,如ConcurrentHashMap,或者在单线程环境中确保put操作的原子性。 总的来说,马士兵老师的HashMap学习笔记不仅涵盖了HashMap的基础知识,还深入...
而在JDK 1.8中,虽然在某些操作(如put操作)中增加了同步控制,但仍未从根本上解决多线程问题。如果需要线程安全的HashMap,推荐使用ConcurrentHashMap或者Collections.synchronizedMap。 总的来说,HashMap在单...
HashMap 在多线程环境下使用时,需要注意线程安全问题,否则可能会导致程序崩溃或数据不一致。 * 使用 ConcurrentHashMap 替代 HashMap,可以解决线程安全问题。 * 使用线程安全的集合框架,例如 ...
5. **线程不安全**:HashMap不是线程安全的,如果在多线程环境中使用,需要外部同步机制,或者使用ConcurrentHashMap。 6. **null键与null值**:HashMap允许键和值为null,但只有一个键可以为null,且该键对应的值...
死锁是多线程编程中的一种常见问题,发生在两个或更多线程相互等待对方释放资源,从而导致所有线程都无法继续的情况。避免死锁的方法包括避免循环等待、设置超时、使用死锁检测算法等。 线程优先级也是Java多线程中...
Servlet/JSP 技术由于其多线程运行而具有很高的执行效率,但这也意味着需要非常细致地考虑多线程的安全性问题。 Servlet 的多线程机制是建立在 Java 多线程机制之上的。Servlet 容器会自动使用线程池等技术来支持...
4. **并发问题**:HashMap不是线程安全的,这意味着在多线程环境中,同时对HashMap进行读写操作可能会导致数据不一致。如果需要线程安全的哈希表,可以使用`ConcurrentHashMap`。 5. **null值**:HashMap允许键和值...
这意味着在多线程环境中,对`HashTable`的操作不会导致数据不一致的情况发生。 - **HashMap**: 默认是非线程安全的。如果多个线程同时访问一个`HashMap`实例,且至少有一个线程修改了该`HashMap`,则必须通过外部...