ArrayList不安全的实例及解决方案
Posted 圣金巫灵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayList不安全的实例及解决方案相关的知识,希望对你有一定的参考价值。
ArrayList线程不安全例子:
public class ListTest { public static void main(String[] args) { List<String> list = Collections.synchronizedList(new ArrayList<>()); // List<String> list = new Vector<>(); // List<String> list = Collections.synchronizedList(new ArrayList<>()); for (int i = 0; i < 20; i++) { new Thread(()->{ list.add(UUID.randomUUID().toString().substring(0,8)); list.forEach(System.out::println); }).start(); } } }
报错ConcurrentModificationException:
解决:
使用 Vector或者Collections.synchronizedList()方法
使用List<String> list = new CopyOnWriteArrayList<>();
来看看这个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(); } }
final void setArray(Object[] a) { array = a; }
读的时候不加锁。
set同理。也有CopyOnWriteArraySet
public class ListTest { public static void main(String[] args) { Set<String> set = new CopyOnWriteArraySet<>(); for (int i = 0; i < 20; i++) { new Thread(()->{ set.add(UUID.randomUUID().toString().substring(0,8)); set.forEach(System.out::println); }).start(); } } }
但是CopyOnWriteArraySet实际上是CopyOnWriteArrayList:
Map用ConcurrentHashMap, 数组+链表,如果长度大于8,链表成红黑树。
以上是关于ArrayList不安全的实例及解决方案的主要内容,如果未能解决你的问题,请参考以下文章
Python 自动化 - 浏览器chrome打开F12开发者工具自动Paused in debugger调试导致无法查看网站资源问题原因及解决方法,javascript反调试问题处理实例演示(代码片段