ArrayList and LinkedList previously described, in multithreaded scenarios are not appropriate. JDK provides a thread-safe List.
Vector is thread-safe and CopyOnWriteArrayList
1、Vector
The class properties and methods with ArrayList, the main difference is the Vector on its main methods are combined with the synchronized keyword, so that to achieve a thread-safe purposes.
2, CopyOnWriteArrayList source code analysis
public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { final transient ReentrantLock lock = new ReentrantLock(); //使用数组存储数据 private transient volatile Object[] array; }
With respect to the ArrayList, a lock for a multi-thread safe, less counting size
3, CopyOnWriteArrayList constructor
// 1, empty constructor public a CopyOnWriteArrayList () { setArray (new new Object [0]); } // 2, a set of constructors public a CopyOnWriteArrayList (Collection <? The extends E> C) { Object [] Elements; IF (C. getClass () == CopyOnWriteArrayList.class) Elements = ((a CopyOnWriteArrayList <?>) C) .getArray (); the else { Elements c.toArray = (); // c.toArray Might (incorrectly) Not return Object [] ( 6260652 See) IF (elements.getClass () = [] class) Object!. Elements = Arrays.copyOf (Elements, elements.length, Object [] class);. } // assigned to the current Array setArray(elements); } //. 3, the digital Constructor public CopyOnWriteArrayList(E[] toCopyIn) { setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class)); } //setArray方法 final void setArray(Object[] a) { array = a; }
The main argument is parsed into a digital object, and then copied to the array
4, add operation
// 1, adding a single element public Boolean the Add (E E) { } // 2, add a single element to a location public void the Add (int index, E Element) { } //. 3, adding a collection of elements public boolean addAll ( collection <? the extends E> C) { } //. 4, starting from a set position to add public boolean addAll (int index, collection <? extends E> c) {
Analysis of the main public boolean add (E e)
public boolean add(E e) { final ReentrantLock lock = this.lock; //1、获取锁对象 lock.lock(); try { //2、增加元素 Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); newElements[len] = e; setArray(newElements); return true; } finally { //3、释放锁 lock.unlock(); } }
Note that: CopyOnWriteArrayList not ArrayList of automatic expansion (1.5), add an execution Arrays.copyOf operation, this will become a performance bottleneck
5, delete
We mainly look
public E remove(int index) { final ReentrantLock lock = this.lock; //1、获取锁 lock.lock(); try { Object[] elements = getArray(); int len = elements.length; E oldValue = get(elements, index); int numMoved = len - index - 1; if (numMoved == 0) setArray(Arrays.copyOf(elements, len - 1)); else { Object[] newElements = new Object[len - 1]; System.arraycopy(elements, 0, newElements, 0, index); System.arraycopy(elements, index + 1, newElements, index, numMoved); setArray(newElements); } return oldValue; } finally { lock.unlock(); } }
6, modify operation
We look
public E set(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); E oldValue = get(elements, index); if (oldValue != element) { //直接获取元素,并替换 int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len); newElements[index] = element; setArray(newElements); } else { // Not quite a no-op; ensures volatile write semantics setArray(elements); } return oldValue; } finally { lock.unlock(); } }
7, query operation
private E get(Object[] a, int index) { return (E) a[index]; } public E get(int index) { return get(getArray(), index); }
Get here is not thread safe.
And Vector query operation, synchronized modification, are thread-safe.
public synchronized E get(int index) { if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); return elementData(index); }
Summary: In Vector, regardless of additions and deletions operation, or query operation, all are coupled with synchronized lock,
In CopyOnWriteArrayList, only CRUD operations added a lock, there is no inquiry, so that multiple threads can be accessed in parallel.