ArraysList is a thread-unsafe data type. If multiple threads are accessing the list instance at the same time, and at least one thread is structurally modifying the list, external synchronization is required. Use the Collections. SychronizedList method is thread-safe.

Looking at the JDK documentation, there are ways to structurally modify ArraysList

ElementData [size++] = e; elementData[size++] = e; There is a risk of thread insecurity.

ElementData and size are both global variables, but without sychronization, elementData is shared thread unsafe mutable data.

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 intsize; .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++; }}Copy the code

There is a risk of thread insecurity in the Iterator part. One reason is that the iterator part uses ArraysList’s add method arrayList.this.add (I, e) directly; , but no sychronization synchronization is performed.

   public ListIterator<E> listIterator(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: "+index);
        return new ListItr(index);
    }
    public ListIterator<E> listIterator(a) {
        return new ListItr(0);
    }

    public Iterator<E> iterator(a) {
        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 newConcurrentModificationException(); }}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 newConcurrentModificationException(); }}}Copy the code

conclusion

This article analyzes the causes of the insafety of ArraysList threads by using add and Iterator.