在这篇文章中,我们将讨论来自java.util.concurrent
包的CopyOnWriteArrayList
。
这是一个在多线程程序中非常有用的结构--当我们想以线程安全的方式迭代一个列表而不需要明确的同步。
ArrayList的线程安全变体,其中所有的变异操作(添加、设置等)都是通过对底层数组进行新的复制来实现的。
通常情况下,CopyOnWriteArrayList
是非常昂贵的,因为它涉及到每次写操作的昂贵的数组拷贝,但是如果你有一个迭代次数超过变异次数的List,那么它就非常有效,例如,你主要需要迭代ArrayList,而不需要经常修改它。
CopyOnWriteArrayList
类构造函数的总结CopyOnWriteArrayList
类方法 类的方法CopyOnWriteArrayList
类的例子CopyOnWriteArrayList()
- 创建一个空列表。CopyOnWriteArrayList(Collection<? extends E> c)
- 创建一个包含指定集合元素的列表,其顺序是由集合的迭代器返回。CopyOnWriteArrayList(E[] toCopyIn)
- 创建一个包含给定数组副本的列表。在类的下面,图中显示了CopyOnWriteArrayList
类方法的列表。
阅读更多关于CopyOnWriteArrayList类方法的内容 CopyOnWriteArrayList Javadoc 8.
我们知道CopyOnWriteArrayList
的迭代器是fail-safe
,不会抛出ConcurrentModificationException
。让我们通过例子来证明这一点。
首先让我们用一个例子来证明ArrayList的迭代器是fail-fast
并且抛出ConcurrentModificationException
。
public class CopyOnWriteArrayListExample {
private static List<Integer> list = new ArrayList<>();
public static void main(final String[] args) {
list.add(1);
list.add(2);
list.add(3);
final Runnable runnable = () -> {
list.add(4);
list.add(5);
};
final Thread thread = new Thread(runnable);
thread.start();
final Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
final Integer integer = iterator.next();
System.out.println(integer);
}
}
}
输出。
1
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at com.javaguides.collections.specialpurposeimpl.CopyOnWriteArrayListExample
.main(CopyOnWriteArrayListExample.java:33)
注意,在上面的例子中,我们是通过创建一个独立的线程来修改ArrayList的。
现在,让我们用CopyOnWriteArrayList
类替换ArrayList,看看输出结果。
下面是源代码。
//*/*
/*
/* This program demonstrates how CopyOnWriteArrayList works.
/*
/* @author www.javaguides.net
/*/
public class CopyOnWriteArrayListExample {
private static List<Integer> list = new CopyOnWriteArrayList<>();
publicstaticvoidmain(finalString[] args) {<<$2$>>
}
输出。
1
2
3
4
5
注意,CopyOnWriteArrayList
的迭代器是安全的,不会抛出ConcurrentModificationException
。
创建CopyOnWriteArrayList
是为了允许在底层列表被修改时也能安全地迭代元素。
由于复制机制,不允许对返回的Iterator进行remove()
操作--结果是UnsupportedOperationException
。
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
//*/*
/*
/* This program demonstrates how CopyOnWriteArrayList works.
/*
/* @author www.javaguides.net
/*/
public class CopyOnWriteArrayListExample {
private static List<Integer> list = new CopyOnWriteArrayList<>();
public static void main(final String[] args) {
list.add(1);
list.add(2);
list.add(3);
final Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
final Integer integer = iterator.next();
iterator.remove();
System.out.println(integer);
}
}
}
输出。
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(CopyOnWriteArrayList.java:1178)
at com.javaguides.collections.specialpurposeimpl.CopyOnWriteArrayListExample.
main(CopyOnWriteArrayListExample.java:25)
###参考文献
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.javaguides.net/2018/08/copyonwritearraylist-in-java.html
内容来源于网络,如有侵权,请联系作者删除!