多线程环境下,List、Set、Map均是线程不安全集合,如果不采用措施,并发访问就会报错。
样例一:
package com.zhang;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
public class ContainerNotSafeDemoList {
public static void main(String[] args) {
//List场景
List list = new ArrayList();
for (int i=0;i<30;i++){
new Thread(() ->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
报错如下:
解决方案:
package com.zhang;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
public class ContainerNotSafeDemoList {
public static void main(String[] args) {
//List场景
//List list = new ArrayList();
//List list = new Vector();解决方案1
//List list = Collections.synchronizedList(new ArrayList<>());解决方案2
//解决方案3 CopyOnWriteArrayList
//CopyOnWrite是写时复制的容器,添加时首先对当前容器object[]拷贝得到object[] newElements
//然后新容器里面添加元素之后,将原容器引用指向新容器。
//好处是可以并发的读,不需要加锁,因为当前容器不会添加任何元素,是一种读写分离思想
List list = new CopyOnWriteArrayList();
//Set场景,
//底层也是HashMap,其中set.add(key),其value存储的是固定的对象PRESENT = new Object()
//Set set = new HashSet();
//Set set = Collections.synchronizedSet(new HashSet<>());解决方案1
Set set = new CopyOnWriteArraySet();解决方案2
//Map场景
//Map map = new HashMap();
//Map map = Collections.synchronizedMap(new HashMap());解决方案1
Map map = new ConcurrentHashMap();//解决方案2
for (int i=0;i<30;i++){
new Thread(() ->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
},String.valueOf(i)).start();
}
}
}
测试结果: