标签:方案 cti 集合 cto present ring init length rand
一、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、解决方案
在读多写少的时候推荐使用 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、解决方案:
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、解决方案
标签:方案 cti 集合 cto present ring init length rand
原文地址:https://www.cnblogs.com/wjh123/p/11259409.html