Chapter3 集合的线程不安全问题
3.1 ArrayList
- 举例说明其线程不安全
报错:public static void main(String[] args) { List<String> list = new ArrayList<>(); 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(); } }ConcurrentModificationException(并发修改异常)
- 解决方法
- 使用
Vector代替ArrayList:Vector使用了synchronsized - 使用
Collections工具类:List<String> list = Collections.synchronizedList(new ArrayList<>()); - 使用
CopyOnWriteArrayList代替ArrayList:List<String> list = new CopyOnWriteArrayList();
- 使用
3.2 HashSet
- 举例说明其线程不安全
public static void main(String[] args) { Set<String> set = new HashSet<>(); for (int i = 0; i < 300; i++) { new Thread(()->{ set.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(set); }, String.valueOf(i)).start(); } }Hashset底层为HashMap,value为常量。 - 解决方法
- 使用
Collections工具类:Set<String> set = Collections.synchronizedSet(new HashSet<>()); - 使用
CopyOnWriteArraySet代替HashSet:Set<String> set = new CopyOnWriteArraySet();
- 使用
3.3 HashMap
- 举例说明其不安全
public static void main(String[] args) { Map<String,String> map = new java.util.HashMap(); for (int i = 0; i < 300; i++) { new Thread(()->{ map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0, 8)); System.out.println(map); }).start(); } } - 解决方法
- Map<String,String> map = new ConcurrentHashMap<>();