详解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,因此永远都不会抛出安全失败的异常。但也是因为这个,无法保证读取的数据是目前原始数据结构中的数据。

 

 

 

 

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值