1.ArrayList集合线程不安全
当有多个线程同时往ArrayList容器中加入数据,并读取数据时,会出现并发修改异常
package com.company.list;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ThreadDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// 第一种解决线程不安全的解决方案,该方案性能较低,一般不采用
// List list = new Vector();
// 第二种解决线程不安全的解决方案,使用Collections工具类
// List<String> list = Collections.synchronizedList(new ArrayList<>());
// 第三种方案采用CopyOnWriteArrayList(即写时复制技术)
// List<String> list = new CopyOnWriteArrayList<>();
for(int i = 0;i < 30;i++){
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
},""+i).start();
}
}
}
异常如下:
Exception in thread "23" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.io.PrintStream.println(PrintStream.java:821)
at com.company.list.ThreadDemo.lambda$main$0(ThreadDemo.java:18)
at java.lang.Thread.run(Thread.java:748)
1.1 解决方案一
使用Vector,但不推荐使用,因为使用该类性能较低
List<String> list= new Vector<>();
1.2 解决方案二
使用Collections工具类
List<String> list = Collections.synchronizedList(new ArrayList<>());
1.3 解决方案三(最佳)
使用CopyOnWriteArrayList
原理:CopyOnWriteArrayList采用了写时复制技术,在有多个线程来并发读取数据时不会上锁,而在有多个线程来修改数据时会上锁,它会将原来的容器拷贝一份,然后在新容器上修改,修改之后再将新容器把旧容器覆盖掉
List<String> list= new CopyOnWriteArrayList<>();
2.HashSet线程不安全
使用CopyOnWriteArraySet
Set<String> set = new CopyOnWriteArraySet<>();
3.HashMap线程不安全
使用ConcurrentHashMap
Map<String,String> map = new ConcurrentHashMap<>();