多线程中的集合是不安全的
package com.collection; import java.util.ArrayList; import java.util.List; /** * @author liuxu * @date 2021/11/11 22:28 */ public class ArrayListDemo { public static void main(String[] args) { List<Integer> integers = new ArrayList<>(); for (int i = 0; i < 10; i++) { Integer tem = i; new Thread(()->{ integers.add(tem); System.out.println(integers); }).start(); } } }
多跑几次就会出错
Exception in thread "Thread-1" Exception in thread "Thread-0" java.util.ConcurrentModificationException
解决方案
1.用Vector
2.用 Collections.synchronizedList(new ArrayList<>());
3.用CopyOnWriteArrayList 底层的add get方法用到了可重入锁ReentrantLock。而且用的不是同一个锁,实现读写分离,写时复制
同样set也不安全
解决方案
1.Collections.synchronizedSet(new HashSet<>());
2.Set<Integer> set = new CopyOnWriteArraySet<>(); 底层CopyOnWriteArrayList
set底层是HashMap set的add方法是将调用HashMap的put方法,key值放入元素,value值放入的是一个空Obejct private static final Object PRESENT = new Object();
package com.collection; import java.util.ArrayList; import java.util.List; import java.util.Vector; /** * @author liuxu * @date 2021/11/11 22:28 */ public class ArrayListDemo { public static void main(String[] args) { List<Integer> integers = new Vector<>(); //List<Integer> integers = Collections.synchronizedList(new ArrayList<>()); // List<Integer> integers = new CopyOnWriteArrayList(); // Set<Integer> set = Collections.synchronizedSet(new HashSet<>()); for (int i = 0; i < 10; i++) { Integer tem = i; new Thread(()->{ integers.add(tem); System.out.println(integers); }).start(); } } }
map 同样不安全
解决方案
1.用Map<String,String> map = new ConcurrentHashMap<>();
2.用Map<String,String> map = Collections.synchronizedMap(new HashMap<>());
package com.collection; import java.util.HashMap; import java.util.Map; /** * @author liuxu * @date 2021/11/11 22:58 */ public class MapDemo { public static void main(String[] args) { Map<String,String> map = new HashMap(); for (int i = 0; i < 20; i++) { int tem = i; new Thread(()->{ map.put("key"+tem,"val"+tem); System.out.println(map); }).start(); } } }