以下是一个简单的示例,展示了使用 Java 的 HashMap
实现的线程不安全和线程安全的情况:
线程不安全的例子:
import java.util.HashMap;
public class UnsafeHashMapExample {
public static void main(String[] args) {
HashMap<Integer, String> map = new HashMap<>();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
map.put(i, "Value" + i);
}
};
// 创建两个线程,并发修改 HashMap
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出 HashMap 的大小,预期结果应该小于 2000
System.out.println("HashMap size: " + map.size());
}
}
在这个例子中,两个线程同时向同一个 HashMap 中添加元素,这会导致竞争条件和线程安全问题。由于 HashMap
不是线程安全的,因此可能会导致数据丢失或不一致的情况。
线程安全的例子:
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class SafeHashMapExample {
public static void main(String[] args) {
Map<Integer, String> map = Collections.synchronizedMap(new HashMap<>());
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
map.put(i, "Value" + i);
}
};
// 创建两个线程,并发修改线程安全的 HashMap
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出线程安全的 HashMap 的大小,预期结果应该是 2000
System.out.println("Safe HashMap size: " + map.size());
}
}
在这个例子中,我们使用 Collections.synchronizedMap()
方法创建了一个线程安全的 HashMap,该方法返回一个包装了传入 Map 的同步(线程安全)视图。因此,即使多个线程同时访问该 HashMap,也不会出现线程安全问题。