ArraysList是线程不安全的数据类型。如果多个线程同时访问列表实例,并且至少有一个线程在结构上修改列表,则需要在外部同步。使用
Collections.sychronizedList方法是线程安全的。

查看JDK文档,在结构上修改ArraysList的方法有

分析源码发现,在add方法中的elementData[size++] = e;存在线程不安全的风险。

elementData与size都是全局变量,但没有进行sychronization同步处理,elementData是共享的线程不安全的mutable可变数据。
public class ArrayList<E> extends AbstractList<E> implements List<E>,
RandomAccess, Cloneable, java.io.Serializable { private static final long
serialVersionUID= 8683452581122892189L; private static final int
DEFAULT_CAPACITY= 10; private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; transient
Object[] elementData; // non-private to simplify nested class access private int
size; .................. public boolean add(E e) { ensureCapacityInternal(size
+ 1); // Increments modCount!! elementData[size++] = e; return true; } public
void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal
(size + 1); // Increments modCount!! System.arraycopy(elementData, index,
elementData, index + 1, size - index); elementData[index] = element; size++; } }
在iterator部分存在线程不安全的风险,原因之一是iterator部分直接使用了ArraysList的add方法
ArrayList.this.add(i, e); ,但没有进行sychronization同步处理。
public ListIterator<E> listIterator(int index) { if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index);
} public ListIterator<E> listIterator() { return new ListItr(0); } public
Iterator<E> iterator() { return new Itr(); } /** * An optimized version of
AbstractList.Itr */ private class Itr implements Iterator<E> { .................
...... } /** * An optimized version of AbstractList.ListItr */ private class
ListItr extends Itr implements ListIterator<E> { ........................ public
void set(E e) { if (lastRet < 0) throw new IllegalStateException();
checkForComodification(); try { ArrayList.this.set(lastRet, e); } catch (
IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }
public void add(E e) { checkForComodification(); try { int i = cursor; ArrayList
.this.add(i, e); cursor = i + 1; lastRet = -1; expectedModCount = modCount; }
catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException
(); } } }
<>总结

本文通过add和Iterator入手分析ArraysList线程不安全的原因,可能不够全面,欢迎补充,欢迎指正!

技术
©2019-2020 Toolsou All rights reserved,
基于神经网络的车辆牌照字符识别技术Java基础(三) String深度解析 dedecms网站被黑 劫持到其他网站如何解决精准手机号抓取,运营商大数据利用梆梆加固逻辑漏洞取巧脱壳QT 删除目录及文件Java小明A+B苹果不送充填器耳机真为环保?可能还是为了赚钱吧在Pytorch上使用summaryC#中字典的排序方法