集合类不安全-并发修改异常、写时复制
例子
package com.example.demo;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author :
* @date :Created in 2021/11/4 11:24
* @description:
*/
public class ContainerNotSafeDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
List<String> list2 = new Vector<>();
List<String> list3 = Collections.synchronizedList(new ArrayList<>());
List<String> list4 = new CopyOnWriteArrayList();
for (int i = 0; i <= 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);// 结果 并发修改异常 java.util.ConcurrentModificationException
list2.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list2);
list3.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list3);
list4.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list4);
}, String.valueOf(i)).start();
}
}
}
使用 List list = new ArrayList<>(); 会出问题java.util.ConcurrentModificationException
使用其他三种方式可解决
List list2 = new Vector<>();
List list3 = Collections.synchronizedList(new ArrayList<>());
List list4 = new CopyOnWriteArrayList();
写时复制
CopyOnWriteArrayList 这个类,add方法
getArray() // 获取Array
Arrays.copyOf() // 进行长度加1
newElement[len] = e // 数组赋值
setArray(newElement) // 放入新的值
HashSet 不安全
public static void main(String[] args) {
Set<String> set = new HashSet<>(); // 结果 并发修改异常 java.util.ConcurrentModificationException
Set<String> set2 = Collections.synchronizedSet(new HashSet<>());
Set<String> set3 = new CopyOnWriteArraySet<>();
for (int i = 0; i <= 30; i++) {
new Thread(() -> {
set.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(set);
}, String.valueOf(i)).start();
}
}
HashSet 底层
底层是HashMap,进行add方法时。操作key值。value值为Object。
HashMap 不安全
public static void main(String[] args) {
Map<String,String> map = new HashMap<>(); // 结果 并发修改异常 java.util.ConcurrentModificationException
Map<String,String> map2 = Collections.synchronizedMap(new HashMap<>());
Map<String,String> map3 = new ConcurrentHashMap<>();
for (int i = 0; i <= 30; i++) {
new Thread(() -> {
map3.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,8));
System.out.println(map3);
}, String.valueOf(i)).start();
}
}