CopyOnWriteArrayList中写操作需要大面积复制数组,所以性能肯定很差,但是读操作因为操作的对象和写操作不是同一个对象,读之间也不需要加锁,读和写之间的同步处理只是在写完后通过一个简单的"="将引用指向新的数组对象上来,这个几乎不需要时间,
什么是fail-safe?
答:当我们对集合结构上做出改变的时候,fail-fast机制就会抛出异常。但是,对于采用fail-safe机制来说,就不会抛出异常
这是因为,当集合的结构被改变的时候,fail-safe机制会在复制原集合的一份数据出来,然后在复制的那份数据遍历。
什么是fail-fast?
答:fail-fast的字面意思是“快速失败”。当我们在遍历集合元素的时候,经常会使用迭代器,但在迭代器遍历元素的过程中,如果集合的结构被改变的话,就会抛出异常,防止继续遍历。这就是所谓的快速失败机制。fail-fast,即快速失败机制,它是java集合中的一种错误检测机制,当多个线程(单个线程也是可以滴),在结构上对集合进行改变时,就有可能会产生fail-fast机制。
fail-fast和fail-safe有什么区别?
答:
fail-safe机制fail-safe任何对集合结构的修改都会在一个复制的集合上进行修改,因此不会抛出ConcurrentModificationException
fail-safe机制有两个问题
(1)需要复制集合,产生大量的无效对象,开销大
(2)无法保证读取的数据是目前原始数据结构中的数据。
fail-fast机制fail-fast机制在遍历一个集合时,当集合结构被修改,会抛出Concurrent Modification Exception。
fail-fast会在以下两种情况下抛出ConcurrentModificationException
(1)单线程环境
集合被创建后,在遍历它的过程中修改了结构。
注意 remove()方法会让expectModcount和modcount 相等,所以是不会抛出这个异常。
(2)多线程环境
当一个线程在遍历这个集合,而另一个线程对这个集合的结构进行了修改。
HashSet的底层实现原理是什么?
答:HashSet底层依赖与HashMap进行数据存储,HashSet的元素就是HashMap中的Key,而Value则为Null
怎么确保一个集合不能被修改?
答:两种实现方式,Collections. unmodifiableCollection(Collection c) 方法创建的集合(
最终会返回一个由Collections.UnmodifiableCollection类,该类对所有的写操作都进行了重写覆盖,使其抛出UnsupportedOperationException异常),和使用Arrays.asList创建的集合(返回了一个Arrays的静态内部类ArrayList,原理与Collections.UnmodifiableCollection差不多)。