publicbooleanadd(E e){ final ReentrantLock lock = this.lock; lock.lock();//先加锁 try { Object[] elements = getArray(); int len = elements.length; //复制到新数组中,长度+1 Object[] newElements = Arrays.copyOf(elements, len + 1); //在新数组中添加元素 newElements[len] = e; //将新数组设置给array setArray(newElements); returntrue; } finally { lock.unlock(); } }
指定位置插入
publicvoidadd(int index, E element){ final ReentrantLock lock = this.lock; // 加锁 lock.lock(); try { // 获取旧数组 Object[] elements = getArray(); int len = elements.length; // 检查是否越界, 可以等于len if (index > len || index < 0) thrownew IndexOutOfBoundsException("Index: "+index+ ", Size: "+len); Object[] newElements; int numMoved = len - index; if (numMoved == 0) // 如果插入的位置是最后一位 // 那么拷贝一个n+1的数组, 其前n个元素与旧数组一致 newElements = Arrays.copyOf(elements, len + 1); else { // 如果插入的位置不是最后一位 // 那么新建一个n+1的数组 newElements = new Object[len + 1]; // 拷贝旧数组前index的元素到新数组中 System.arraycopy(elements, 0, newElements, 0, index); // 将index及其之后的元素往后挪一位拷贝到新数组中 // 这样正好index位置是空出来的 System.arraycopy(elements, index, newElements, index + 1, numMoved); } // 将元素放置在index处 newElements[index] = element; setArray(newElements); } finally { // 释放锁 lock.unlock(); } }
addIfAbsent
//添加一个不存在于集合中的元素。 publicbooleanaddIfAbsent(E e){ // 获取元素数组 Object[] snapshot = getArray(); //已存在返回false,否则添加 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) { // 重新检查元素是否在刚获取的数组里,减少indexOf的对比次数 int common = Math.min(snapshot.length, len); for (int i = 0; i < common; i++) //判断是否有线程指定下标添加了元素 if (current[i] != snapshot[i] && eq(e, current[i])) returnfalse; if (indexOf(e, current, common, len) >= 0) returnfalse; } // 拷贝一份n+1的数组 Object[] newElements = Arrays.copyOf(current, len + 1); // 将元素放在最后一位 newElements[len] = e; setArray(newElements); returntrue; } finally { // 释放锁 lock.unlock(); } }
获取元素
public E get(int index){ return get(getArray(), index); } final Object[] getArray() { return array; } //私有方法 private E get(Object[] a, int index){ return (E) a[index]; }