List线程不安全与解决方案
/**
* list 线程不安全,可能出现ConcurrentModificationException并发修改异常
*/
public class ThreadDemo4 {
public static void main(String[] args) {
//创建ArrayList集合
// List<String> list = new ArrayList<>();
//解决方案1: Vector
// List<String> list = new Vector<>();
//解决方案2: Collections.synchronizedList
// List<String> list = Collections.synchronizedList(new ArrayList<>());
//解决方案3: CopyOnWriteArrayList
List<String> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 300; i++) {
new Thread(()->{
//向集合添加内容
list.add(UUID.randomUUID().toString().substring(0,8));
//从集合索引内容
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
解决方案-Vector
Vector的add方法是加了synchronized关键字的,这是一种很古老的解决方法
解决方案-Collections
List<String> list = Collections.synchronizedList(new ArrayList<>());
效率不高,使用的也不多
解决方案-CopyOnWriteArrayList
来自于JUC包下
CopyOnWriteArrayList原理: 写时复制技术,写的时候复制一份一样的,加入新的内容,然后再覆盖合并之前的。
HashSet、HashMap线程不安全与解决方案
// Set<String> set = new HashSet<>();
//HashSet解决方案:CopyOnWriteArraySet
// Set<String> set = new CopyOnWriteArraySet<>();
// Map<String, String> map = new HashMap<>();
//HashMap解决方案:ConcurrentHashMap
Map<String, String> map = new ConcurrentHashMap<>();
for (int i = 0; i < 300; i++) {
String key = String.valueOf(i);
new Thread(()->{
//向集合添加内容
map.put(key, UUID.randomUUID().toString().substring(0,8));
//从集合索引内容
System.out.println(map);
},String.valueOf(i)).start();
}