Ali*_*aka 248 java concurrency list
如何创建并发List实例,我可以通过索引访问元素?JDK是否有我可以使用的任何类或工厂方法?
小智 159
java.util.concurrent中有一个并发列表实现.特别是CopyOnWriteArrayList.
Mat*_*ell 146
如果您不关心具有基于索引的访问权限并且只想要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
}
Run Code Online (Sandbox Code Playgroud)
Yan*_*hon 121
如果你需要的只是简单的调用同步,你可以很好地使用Collections.synchronizedList(List):
List<Object> objList = Collections.synchronizedList(new ArrayList<Object>());
Run Code Online (Sandbox Code Playgroud)
Joa*_*uer 43
因为获取位置并从给定位置获取元素的行为自然需要一些锁定(您不能让列表在这两个操作之间进行结构更改).
并发集合的想法是每个操作本身都是原子操作,可以在没有显式锁定/同步的情况下完成.
因此,在预期并发访问的情况下,将元素n从给定的位置List作为原子操作获得并不太有意义.
Oli*_*liv 27
您有以下选择:
Collections.synchronizedList():您可以包装任何List实现(ArrayList,LinkedList或第 3 方列表)。对每种方法(读取和写入)的访问都将使用synchronized. 使用iterator()或增强for循环时,必须手动同步整个迭代。在迭代时,其他线程甚至无法读取。您也可以为每个hasNext和next呼叫分别同步,但这ConcurrentModificationException是可能的。
CopyOnWriteArrayList: 修改成本高,但无需等待阅读。迭代器从不 throw ConcurrentModificationException,它们在迭代器创建时返回列表的快照,即使列表在迭代时被另一个线程修改。对不经常更新的列表很有用。批量操作喜欢addAll更新 - 内部数组被复制的次数更少。
Vector: 非常像synchronizedList(new ArrayList<>()),但迭代也是同步的。但是,ConcurrentModificationException如果向量在迭代时被另一个线程修改,则迭代器可能会抛出异常。
其他选项:
Queue或者Deque如果您只在列表的末尾添加/删除或迭代它,则可能是另一种选择。Queue只允许在一端添加并从另一端Deque删除,允许在两端添加和删除。没有索引访问。有多种实现具有比任何实现都更好的并发属性List。查看Queue javadoc中的“所有已知实现类”,java.util.concurrent包中的那些实现是并发的。您还可以查看JCTools,它包含专用于单个消费者或单个生产者的更快的队列实现。Collections.unmodifiableList(): 无等待,线程安全,但不可修改List.of& List.copyOf:Java 9 及更高版本中的另一个不可修改的列表。CopyOnWriteArrayList 是 ArrayList 的线程安全变体,其中所有可变操作(添加、设置等)都是通过制作底层数组的新副本来实现的。
CopyOnWriteArrayList 是同步 List 的并发替代方案,实现 List 接口及其 java.util.concurrent 包的一部分及其线程安全集合。
public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Run Code Online (Sandbox Code Playgroud)
CopyOnWriteArrayList 是故障安全的,并且在使用 ArrayList 的单独副本进行迭代期间修改基础 CopyOnWriteArrayList 时不会引发 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();
}
}
Run Code Online (Sandbox Code Playgroud)
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
| 归档时间: |
|
| 查看次数: |
266866 次 |
| 最近记录: |