返回

HashMap线程不安全的深层次剖析:示例代码揭秘

后端

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是线程安全的集合类。