java面试-集合类不安全问题及解决方案
Posted wjh123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java面试-集合类不安全问题及解决方案相关的知识,希望对你有一定的参考价值。
一、List
1、代码演示
public class ArrayListNotSafeDemo public static void main(String[] args) List<String> list = new ArrayList<>(); for (int i = 1; i <= 30; i++) new Thread(() -> //Constructs an empty list with an initial capacity of ten. list.add(UUID.randomUUID().toString().substring(0, 8)); System.out.println(list); , String.valueOf(i)).start();
2、故障现象
java.util.ConcurrentModificationException
3、导致原因
一个线程正在写,另一线程过来抢夺,导致数据不一致,即并发修改导致的异常
4、解决方案
- new Vector<>()
- Collections.synchronizedList()
- new CopyOnWriteArrayList<>()
在读多写少的时候推荐使用 CopeOnWriteArrayList 这个类
写时复制,读写分离的思想 好处:读操作完全无锁
使用场景 :写操作非常少的场合,能容忍读写的短暂不一致。
CopyOnWriteArrayList迭代器是只读的,不支持增删改。
5、 CopyOnWriteArrayList源码解读:
public boolean add(E e) final ReentrantLock lock = this.lock; lock.lock(); try Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); newElements[len] = e; setArray(newElements); return true; finally lock.unlock();
二、Set
1、代码演示:
public class HashSetNotSafeDemo public static void main(String[] args) Set<String> list = new HashSet<>(); for (int i = 1; i <= 30; i++) new Thread(() -> list.add(UUID.randomUUID().toString().substring(0, 8)); System.out.println(list); , String.valueOf(i)).start();
2、解决方案:
- Collections.synchronizedSet()
- new CopyOnWriteArraySet<>()
3、CopyOnWriteArraySet底层源码:
底层使用CopyOnWriteArrayList
public CopyOnWriteArraySet() al = new CopyOnWriteArrayList<E>();
4、HashSet底层源码
HashSet的key是你add()的值,value是一个叫PRESENT Object类型的常量,即HashSet只关心key
public HashSet() map = new HashMap<>(); private static final Object PRESENT = new Object(); public boolean add(E e) return map.put(e, PRESENT)==null;
三、Map
1、代码演示:
public class HashMapNotSafeDemo public static void main(String[] args) Map<String, String> map = new HashMap<>(); for (int i = 1; i <= 30; i++) new Thread(() -> map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 8)); System.out.println(map); , String.valueOf(i)).start();
2、解决方案
- Collections.synchronizedMap()
- new ConcurrentHashMap<>();
以上是关于java面试-集合类不安全问题及解决方案的主要内容,如果未能解决你的问题,请参考以下文章
Java并发多线程编程——集合类线程不安全之HashMap的示例及解决方案
面试官系统精讲Java源码及大厂真题系列之Java线程安全的解决办法
Java并发多线程编程——集合类线程不安全之HashSet的示例及解决方案