详解fail-safe的实现机制

运行程序:

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

public class Fail {
	public static void main(String[] args) {
		CopyOnWriteArrayList <Integer>list=new CopyOnWriteArrayList<>();
		list.add(9);
		list.add(5);
		list.add(2);
		list.add(7);
		Iterator <Integer>iter=list.iterator();
		while(iter.hasNext()) {
			list.add(10);
			System.out.println(iter.next());
		}	
	}
}

打印结果为:9  5  2  7 

没有抛出 ConcurrentModificationException , 但是新插入的4个10,也没有打印出来。

再运行下面程序:

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

public class Fail {
	public static void main(String[] args) {
		CopyOnWriteArrayList <Integer>list=new CopyOnWriteArrayList<>();
		list.add(9);
		list.add(5);
		list.add(2);
		list.add(7);
		Iterator <Integer>iter=list.iterator();
		while(iter.hasNext()) {
			list.add(10);
			iter.next();
//			System.out.println(iter.next());
		}
		
		iter=list.iterator();
		while(iter.hasNext()) {
			System.out.println(iter.next());
		}
	}
}

打印结果:9  5  2  7  10  10  10  10

那么为什么会出现这种情况呢?明明4个10被插入进了集合却没有打印出来。

在取得一个Iterater时:

Iterator <Integer>iter=list.iterator();

CopyOnWriteArrayList 类中 iterator的操作是这样的:

public Iterator<E> iterator() {
        return new COWIterator<E>(getArray(), 0);
    }

打开getArray();  可以看到他是将CopyOnWriteArrayList 类中的数组array作为参数传到了COWIterator()中。

    final Object[] getArray() {
        return array;
    }

打开类COWIterator(以下为该类的部分代码),可以看到他是CopyOnWriteArrayList的内部类,实现了ListIterator接口。

static final class COWIterator<E> implements ListIterator<E> {
        /** Snapshot of the array */
        private final Object[] snapshot;
        /** Index of element to be returned by subsequent call to next.  */
        private int cursor;

        COWIterator(Object[] elements, int initialCursor) {
            cursor = initialCursor;
            snapshot = elements;
        }

        public boolean hasNext() {
            return cursor < snapshot.length;
        }

        public boolean hasPrevious() {
            return cursor > 0;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            if (! hasNext())
                throw new NoSuchElementException();
            return (E) snapshot[cursor++];
        }

        @SuppressWarnings("unchecked")
        public E previous() {
            if (! hasPrevious())
                throw new NoSuchElementException();
            return (E) snapshot[--cursor];
        }

        public int nextIndex() {
            return cursor;
        }

        public int previousIndex() {
            return cursor-1;
        }
}

可以看到,我们所得到的Iterator中的elements只是CopyOnWriteArrayList中array的拷贝,当对CopyOnWriteArrayList中array操作时并不会影响到Iterator中的elements,因此永远都不会抛出安全失败的异常。但也是因为这个,无法保证读取的数据是目前原始数据结构中的数据。

猜你喜欢

转载自blog.csdn.net/weixin_41891854/article/details/81750387
今日推荐