并发下的集合类不安全问题解决

List<String> list = new CopyOnWriteArrayList<>();
for (int i =1; i <= 10; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));//随机生成五个字符串
System.out.println(list);
},String.valueOf(i)).start();
}

List解决方案:
1、List<String> list = new Vector<>();
2、List<String> list = Collections.synchronizedList(new ArrayList<>());
3、List<String> list = new CopyOnWriteArrayList<>();

CopyOnWrite 写入时复制 COW 计算机程序设计领域的一种优化策略。
可能出现的问题:多个线程调用的时候,调用的资源list是唯一的,读取的时候是固定的,但是写入的时候不能同时写,后面写的可能把前面写的覆盖掉
---CopyOnWrite 就是在写入的时候复制一份给调用者,调用者操作完之后在把数据丢回去,避免写入的时候直接覆盖造成数据问题。---
为什么不是用Vector呢,因为Vector是Synchronized同步,效率相对来说比较低,
Vector的add方法jdk1.0的时候就已经出现了,解决List并发下的安全问题,带上了Synchronized
ArrayList的add方法在jdk1.2才出现,什么都没有带,这就说明了一个问题
Vector的方法并不是最高效的解决方案
所以使用Collections工具类的方法或JUC的写入时复制(CopyOnWriteArrayList)解决线程并发问题。








set解决方案:
1、Set<String> set = Collections.synchronizedSet(new HashSet<>());
2、Set<String> set = new CopyOnWriteArraySet();

hashSet底层:
底层就是一个hashMap
public HashSet(){
  map = new HashMap<>();
}
set的本质就是map的key key是无法重复的
set的add方法:
public boolean add(E e){
  return map.put(e,PRESENT)==null;
}

PRESENT:
private static final Object PRESENT = new Object();


Hashmap解决方案:
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
Map<String, String> map = new ConcurrentHashMap<>();




原文地址:https://www.cnblogs.com/jzspace/p/12950729.html