返回
HashMap线程不安全的深层次剖析:示例代码揭秘
后端
2023-11-08 21:15:20
HashMap的线程不安全示例
HashMap作为一种广泛应用的集合框架,却有着线程不安全的天生缺陷,理解其线程不安全的本质至关重要。本文将通过示例代码深入剖析HashMap的线程不安全问题,为开发者提供切实可行的解决方案。
示例 1:多线程环境下的ConcurrentModificationException
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class HashMapThreadUnsafeExample1 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
ExecutorService executorService = Executors.newFixedThreadPool(2);
// 线程 1 负责向map中添加元素
executorService.submit(() -> {
for (int i = 0; i < 100; i++) {
map.put("key" + i, i);
}
});
// 线程 2 负责从map中读取元素
executorService.submit(() -> {
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
});
executorService.shutdown();
}
}
在上述代码中,HashMap在多线程环境下使用,线程1和线程2并发操作HashMap。由于HashMap的线程不安全特性,当线程2试图遍历HashMap时,可能出现ConcurrentModificationException异常。
示例 2:通过Hashtable解决HashMap的线程不安全问题
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class HashMapThreadUnsafeExample2 {
public static void main(String[] args) {
Map<String, Integer> map = new Hashtable<>();
ExecutorService executorService = Executors.newFixedThreadPool(2);
// 线程 1 负责向map中添加元素
executorService.submit(() -> {
for (int i = 0; i < 100; i++) {
map.put("key" + i, i);
}
});
// 线程 2 负责从map中读取元素
executorService.submit(() -> {
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
});
executorService.shutdown();
}
}
通过使用Hashtable替换HashMap,上述代码可以解决线程不安全问题,因为Hashtable是线程安全的集合类。