如何实现线程安全的HashMap

请写出一个简单的程序代码,辛苦了~
我的意思是写出一个简单的程序,使程序中的HashMap在该程序里实现线程安全,我仅仅需要这个例子。

  有2种办法让HashMap线程安全,分别如下:
  方法一:通过Collections.synchronizedMap()返回一个新的Map,这个新的map就是线程安全的。 这个要求大家习惯基于接口编程,因为返回的并不是HashMap,而是一个Map的实现。
  方法二:重新改写了HashMap,具体的可以查看java.util.concurrent.ConcurrentHashMap. 这个方法比方法一有了很大的改进。
温馨提示:内容为网友见解,仅供参考
第1个回答  2018-07-28
有2种办法让HashMap线程安全,分别如下:
方法一:通过Collections.synchronizedMap()返回一个新的Map,这个新的map就是线程安全的。 这个要求大家习惯基于接口编程,因为返回的并不是HashMap,而是一个Map的实现。
方法二:重新改写了HashMap,具体的可以查看java.util.concurrent.ConcurrentHashMap. 这个方法比方法一有了很大的改进。本回答被网友采纳
第2个回答  2015-07-07
直接用HashTable,HashTable线程安全。
我一般都会hashmap凡是在一个方法内部new并且不传到方法外面的基本上可以用hashmap,线程不安全的时候用currenthashmap。
比如类属性是map或者静态属性map而且会在不同的线程并发执行操作map时。
第3个回答  2009-08-18
public class MapTest {

public static void main(String[] args) {
final Hashtable<Integer, String> map = new Hashtable<Integer, String>();
map.put(1, "1");
new Thread(new Runnable() {

@Override
public void run() {
Enumeration<String> iterator;
for (int i = 0; i < 5; i++) {
iterator = map.elements();
map.put(i, i + "");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(MapTest.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(iterator.nextElement());
}
}
}).start();
new Thread(new Runnable() {

@Override
public void run() {
Enumeration<String> iterator;
for (int i = 0; i < 5; i++) {
iterator = map.elements();
map.put(i, i + "");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(MapTest.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(iterator.nextElement());
}
}
}).start();
}
}
这是没有异常代码
public class MapTest {

public static void main(String[] args) {
final Hashtable<Integer, String> map = new Hashtable<Integer, String>();
map.put(1, "1");
new Thread(new Runnable() {

@Override
public void run() {
Iterator<Integer> iterator;
for (int i = 0; i < 5; i++) {
iterator = map.keySet().iterator();
map.put(i, i + "");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(MapTest.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(iterator.next());
}
}
}).start();
new Thread(new Runnable() {

@Override
public void run() {
Iterator<Integer> iterator;
for (int i = 0; i < 5; i++) {
iterator = map.keySet().iterator();
map.put(i, i + "");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(MapTest.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(iterator.next());
}
}
}).start();
}
}
这里是有异常代码,Iterator 时产生异常的主要原因,Iterator创建的时候会拿到创建时容器的容量,一个整形数据。 读取的时候就拿这个容量数据先去检查是不是和当前实际容量相等,如果不相等就ConcurrentModificationException异常,相等就开始读数据,所谓线程安全就是一个线程在使用Iterator 读数据的时候,另外线程往里加数据,结果就出现Iterator 保存的容器容量和当前实际容量不等了,就不安全了。
而在hashtable中使用了Enumeration这个线程安全的对象,就是说在另外的线程里加东西的时候他会知道当前容器已经改变,所以使用他是线程安全的。
如果楼主还不明白去开下源代码就知道了。
第4个回答  2019-02-23
在周二面试时,一面的面试官有问到HashMap是否是线程安全的,如何在线程安全的前提下使用HashMap,其实也就是HashMap,Hashtable,ConcurrentHashMap和synchronized
Map的原理和区别。当时有些紧张只是简单说了下HashMap不是线程安全的;Hashtable线程安全,但效率低,因为是Hashtable是使用synchronized的,所有线程竞争同一把锁;而ConcurrentHashMap不仅线程安全而且效率高,因为它包含一个segment数组,将数据分段存储,给每一段数据配一把锁,也就是所谓的锁分段技术。当时忘记了synchronized
Map和解释一下HashMap为什么线程不安全。面试结束后问了下面试官哪里有些不足,面试官说上面这个问题的回答算过关,但可以在深入一些或者自己动手尝试一下。so~~~虽然拿到了offer,但还是再整理一下,不能得过且过啊。

如何让HashMap变成线程安全的
方法一:通过Collections.synchronizedMap()返回一个新的Map,这个新的map就是线程安全的。 这个要求大家习惯基于接口编程,因为返回的并不是HashMap,而是一个Map的实现。方法二:重新改写了HashMap,具体的可以查看java.util.concurrent.ConcurrentHashMap. 这个方法比方法一有了很大的改进。

...HashSet、concurrentHashMap 线程安全,区别,实现原理
而HashMap是非线程安全的,需要通过Collections.synchronizeMap()进行同步。HashSet作为Set接口的实现,不允许重复元素,但添加元素时需要重写hashCode和equals方法以确保唯一性。concurrentHashMap是Java 5引入的线程安全Map实现,它通过分段锁(Segment)提高并发性能。每个Segment是一个小的HashTable,有自己的锁...

hashmap是线程安全的吗
如果你需要一个线程安全的 HashMap,可以选择使用 ConcurrentHashMap。ConcurrentHashMap 是 Java 集合框架的一部分,它提供了线程安全的 HashMap。ConcurrentHashMap 通过使用分段锁技术,允许多个线程在不同的段上进行读写操作,从而提高了并发性能。此外,Java 8 引入的 ConcurrentHashMap.computeIfAbsent ...

ConcurrentHashMap是如何保证线程安全的?
1、ConcurrentHashMap在JDK?1.7中使用的数组?加?链表的结构,其中数组分为两类,大树组Segment?和?小数组?HashEntry,而加锁是通过给Segment添加ReentrantLock重入锁来保证线程安全的。2、ConcurrentHashMap在JDK1.8中使用的是数组?加?链表?加?红黑树的方式实现,它是通过?CAS?或者?synchronized??来保证...

HashMap是线程安全的吗?有什么解决办法?
解决这个问题的方法有三种。一是使用ConcurrentHashMap,它是线程安全的高效替代品。它采用分段锁技术,允许多个线程同时访问不同的数据分段,从而提高并发性能。二是通过Collections.synchronizedMap()方法,将普通的HashMap转化为同步的,虽然简单,但在高并发情况下可能不如ConcurrentHashMap高效。三是利用第...

HashMap 在多线程环境下使用需要注意什么?
需要使用线程安全的实现方式,例如ConcurrentHashMap或者Collections.synchronizedMap()方法将HashMap转换成线程安全的Map。2. 如果在多线程环境下使用HashMap,需要注意线程安全问题,避免出现死循环等问题的发生。3. 如果在多线程环境下使用HashMap,需要注意扩容问题,避免出现链表形成闭环等问题的发生。

如何设计并实现一个线程安全的 Map
要想实现常数级的查找,应该用什么来实现呢?读者应该很快会想到哈希表。确实,Map 底层一般都是使用数组来实现,会借用哈希算法辅助。对于给定的 key,一般先进行 hash 操作,然后相对哈希表的长度取模,将 key 映射到指定的地方。哈希算法有很多种,选哪一种更加高效呢?1. 哈希函数 MD5 和 SHA1 ...

hashmap底层实现原理是什么?
HashMap的实现原理:首先有一个每个元素都是链表(可能表述不准确)的数组,当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了。这时就添加到同一hash值的元素的后面,他们在数组的同一位置,但是形成了链表,同一...

26. 多线程下安全操作 map的方法
此方法在所有方法上使用 synchronized 关键字,限制同一时刻仅有一个线程访问 Map,但可能影响并发性能,尤其是与 ConcurrentHashMap 等其他线程安全 Map 实现相比。在多线程环境进行复合操作时,需额外手动同步以避免其他线程在操作过程中修改 Map。ReentrantLock 是一种 Java 并发编程中的重要工具,提供可...

hashmap线程安全吗
这是因为 HashMap 的设计并没有考虑到线程安全。在 Java 中,有一些线程安全的 Map 实现,如 ConcurrentHashMap,它在多线程环境下提供了更高的性能,这是因为它使用了一种叫做分段锁的技术,允许多个修改操作并行进行。因此,如果你在多线程环境下使用 HashMap,你需要额外的同步控制,比如使用 ...

相似回答