publicstaticvoidmain(String[] args){ List<Integer> data = new CopyOnWriteArrayList<>(); data.add(1); data.add(2); data.add(3); Iterator<Integer>iterator = data.iterator(); while (iterator.hasNext()){ Integer a = iterator.next(); if (a==2){ data.add(4); //modify while traverse over the collection. } System.out.print(String.valueOf(a)+' '); } }
运行结果:
即时我们在遍历过程中对集合进行了添加元素,也不会体现在遍历结果中,因为是在另一个副本中进行添加的。
Fail-safe internal working
看一下是如何对副本进行操作的,以add方法为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
publicbooleanadd(E e){ final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); //return array, which store the element. int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); //array length incremented to original length + 1, and copy the original elements to newElement array. newElements[len] = e; //the last solt is e, which we want to add. setArray(newElements); //set the original array reference to newElements. returntrue; } finally { lock.unlock(); } }
public Iterator<E> iterator(){ returnnew COWIterator<E>(getArray(), 0); //getArray() return the original array reference. } privateCOWIterator(Object[] elements, int initialCursor){ cursor = initialCursor; //traverse the array by snapshot, the snapshot is the original array. elements may receive new array //value, so we need use snapshot to store its reference. snapshot = elements; }
useEffect(() => { // Have a timer call the function every 5 seconds using setInterval const timer = setInterval(() => {}, 5000); return() =>clearInterval(timer); }, []);
/** * CAS tail field. Used only by enq. */ privatefinalbooleancompareAndSetTail(Node expect, Node update){ return unsafe.compareAndSwapObject(this, tailOffset, expect, update); }
intsize(); publicbooleanisEmpty() publicbooleancontains(Object o) publicintindexOf(Object o) public Object[] toArray()//返回一个包含当前所有元素的数组 publicintlastIndexOf(Object o) public E set(int index, E element) public E get(int index) publicvoidadd(int index, E element)//在指定下标插入元素 publicbooleanadd(E e) publicbooleanremove(Object o)//删除指定下标的元素 public E remove(int index) publicvoidclear() publicbooleanaddAll(Collection<? extends E> c)//在当前列表后依次添加c中的元素
privatestaticclassNode<E> { E item; Node<E> next; Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } publicbooleanremoveLastOccurrence(Object o) publicbooleanremoveFirstOccurrence(Object o) public E pop() publicvoidpush(E e) public E pollFirst()//删除链表首部元素 public E pollLast() public E peekFirst()//取得链表头节点 public E peekLast()//取得链表尾节点 publicbooleanofferFirst(E e) publicbooleanofferLast(E e)