如果 index < 0 说明在数组中没有找到指定元素,则直接返回;如果 index >= 0,则调用内部重载方法remove
getArray源码
1 2 3
final Object[] getArray() { return array; }
很简单,直接返回全局array。由于修饰符volatile保证其内存可见性。
indexOf源码
1 2 3 4 5 6 7 8 9 10 11 12 13
privatestaticintindexOf(Object o, Object[] elements, int index, int fence){ if (o == null) { for (int i = index; i < fence; i++) if (elements[i] == null) return i; } else { for (int i = index; i < fence; i++) if (o.equals(elements[i])) return i; } return -1; }
privatebooleanremove(Object o, Object[] snapshot, int index){ final ReentrantLock lock = this.lock; lock.lock(); try { Object[] current = getArray(); int len = current.length;
//下面的if语句的主要功能是:在数组发生变化后,重新定位要移除的元素 if (snapshot != current) findIndex: { //snapshot != current,表示数组被另一个线程操作过,数组元素有变化 int prefix = Math.min(index, len); for (int i = 0; i < prefix; i++) { if (current[i] != snapshot[i] && eq(o, current[i])) { // 找出 current 数组里面 元素 o 所在的位置 i, 并且赋值给 index index = i; break findIndex; //直接跳到findIndex:表示的括号外面 } } if (index >= len) //则说明 元素 o 在另外的线程中已经被删除, 直接 return returnfalse; if (current[index] == o) //index 位置上的元素 o 还在那边, 直接 break break findIndex; index = indexOf(o, current, index, len); // 在 index 与 len 之间寻找元素, 找到位置直接接下来的代码, 没找到 直接 return if (index < 0) returnfalse; } Object[] newElements = new Object[len - 1]; System.arraycopy(current, 0, newElements, 0, index); System.arraycopy(current, index + 1, newElements, index, len - index - 1); setArray(newElements); returntrue; } finally { lock.unlock(); } }
该方法为remove的重载方法。在调用 remove(Object o) 方法时,上个方法会先获取待移除元素所在的位置,然后调用重载方法 remove(Object o, Object[] snapshot, int index) 。在重载方法中,会判断数组是否发生了变化(snapshot != current),如果发生变化的话,则重新定位待删除元素的位置。然后执行移除操作。
public E set(int index, E element){ final ReentrantLock lock = this.lock; lock.lock(); //获取锁 try { Object[] elements = getArray(); E oldValue = get(elements, index); //获取原数组中对应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 确保volatile写语义 setArray(elements); } return oldValue; } finally { lock.unlock(); } }
/** * Appends the element, if not present. * * @param e element to be added to this list, if absent * @return {@code true} if the element was added */ publicbooleanaddIfAbsent(E e){ Object[] snapshot = getArray(); return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false : addIfAbsent(e, snapshot); }
privatebooleanaddIfAbsent(E e, Object[] snapshot){ final ReentrantLock lock = this.lock; lock.lock(); try { Object[] current = getArray(); //获取当前数组 int len = current.length; //获取当前数组的长度 if (snapshot != current) { //期间数组发生了变化。即其他线程有操作了该集合 // Optimize for lost race to another addXXX operation int common = Math.min(snapshot.length, len); //在for循环中,找到,则返回false for (int i = 0; i < common; i++) if (current[i] != snapshot[i] && eq(e, current[i])) returnfalse;
//重新定位待插入元素,如果定位到,则说明已存在,返回FALSE if (indexOf(e, current, common, len) >= 0) returnfalse; }