我如何创建一个并发的列表实例,在那里我可以通过索引访问元素?JDK是否有我可以使用的类或工厂方法?
当前回答
CopyOnWriteArrayList是ArrayList的线程安全变体 所有可变操作(添加、设置等)都由 创建底层数组的新副本。
CopyOnWriteArrayList是同步列表实现列表接口的并发替代,它是java.util.concurrent包的一部分,它是线程安全的集合。
public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
CopyOnWriteArrayList是故障安全的,当底层的CopyOnWriteArrayList在迭代期间使用ArrayList的单独副本被修改时,不会抛出ConcurrentModificationException。
这通常代价太大,因为拷贝数组涉及每个更新操作,将创建一个克隆副本。CopyOnWriteArrayList是频繁读操作的最佳选择。
/**
* Returns a shallow copy of this list. (The elements themselves
* are not copied.)
*
* @return a clone of this list
*/
public Object clone() {
try {
@SuppressWarnings("unchecked")
CopyOnWriteArrayList<E> clone =
(CopyOnWriteArrayList<E>) super.clone();
clone.resetLock();
return clone;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArrayList.html https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CopyOnWriteArrayList.html https://www.logicbig.com/tutorials/core-java-tutorial/java-collections/concurrent-collection-cheatsheet.html
其他回答
因为获取位置和从给定位置获取元素的行为自然需要一些锁定(您不能让列表在这两个操作之间发生结构变化)。
并发收集的思想是,每个操作本身都是原子的,可以在没有显式锁定/同步的情况下完成。
因此,从给定的List中获取位置n的元素作为原子操作在期望并发访问的情况下没有太大意义。
在java.util.concurrent中有一个并发列表实现。特别是CopyOnWriteArrayList。
免责声明:这个答案发表于2011年,在JDK 5之前,也在更高级和最优的并发api之前。因此,虽然下面的方法可以工作,但它不是最好的选择。
如果你需要的只是简单的调用同步,你可以很好地使用Collections.synchronizedList(List):
List<Object> objList = Collections.synchronizedList(new ArrayList<Object>());
ConcurrentLinkedQueue
如果您不关心是否具有基于索引的访问,而只想要List的插入顺序保持特性,那么可以考虑java.util.concurrent.ConcurrentLinkedQueue。因为它实现了Iterable,一旦你添加完所有的项,你可以使用增强的for语法循环内容:
Queue<String> globalQueue = new ConcurrentLinkedQueue<String>();
//Multiple threads can safely call globalQueue.add()...
for (String href : globalQueue) {
//do something with href
}
CopyOnWriteArrayList是ArrayList的线程安全变体 所有可变操作(添加、设置等)都由 创建底层数组的新副本。
CopyOnWriteArrayList是同步列表实现列表接口的并发替代,它是java.util.concurrent包的一部分,它是线程安全的集合。
public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
CopyOnWriteArrayList是故障安全的,当底层的CopyOnWriteArrayList在迭代期间使用ArrayList的单独副本被修改时,不会抛出ConcurrentModificationException。
这通常代价太大,因为拷贝数组涉及每个更新操作,将创建一个克隆副本。CopyOnWriteArrayList是频繁读操作的最佳选择。
/**
* Returns a shallow copy of this list. (The elements themselves
* are not copied.)
*
* @return a clone of this list
*/
public Object clone() {
try {
@SuppressWarnings("unchecked")
CopyOnWriteArrayList<E> clone =
(CopyOnWriteArrayList<E>) super.clone();
clone.resetLock();
return clone;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArrayList.html https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CopyOnWriteArrayList.html https://www.logicbig.com/tutorials/core-java-tutorial/java-collections/concurrent-collection-cheatsheet.html
推荐文章
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- 在Python中插入列表的第一个位置
- 在javascript中从平面数组构建树数组
- Java Regex捕获组
- Openssl不被视为内部或外部命令
- 如何添加自定义方法到Spring Data JPA
- 如何在Ubuntu中设置Java环境路径
- 无法执行dex:在Eclipse中超过GC开销限制
- 有人能解释一下JPA和Hibernate中的mappedBy吗?
- 是什么导致JNI调用变慢?
- Java中的&和&&有什么区别?
- 使用Java的Collections.singletonList()?