- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
根据我的理解,并发集合类优于同步集合,因为并发集合类不会锁定整个集合对象。相反,它们锁定了集合对象的一小部分。
但是当我检查 CopyOnWriteArrayList
的 add
方法时,我们正在获取对完整集合对象的锁定。那为什么 CopyOnWriteArrayList
比 Collections.synchronizedList
返回的列表更好呢?我在 CopyOnWriteArrayList
的 add
方法中看到的唯一区别是每次调用 add
方法时我们都在创建该数组的副本。
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
最佳答案
As per my understanding concurrent collection classes preferred over synchronized collection because concurrent collection classes don't take lock on complete collection object. Instead it takes lock on small segment of collection object.
这对一些集合是正确的,但不是全部。 Collections.synchronizedMap
返回的 map 围绕每个操作锁定整个 map ,而 ConcurrentHashMap
为某些操作只锁定一个哈希桶,或者它可能对其他操作使用非阻塞算法。
对于其他集合,使用的算法和权衡是不同的。 Collections.synchronizedList
返回的列表尤其如此与 CopyOnWriteArrayList
相比.正如您所指出的,synchronizedList
和 CopyOnWriteArrayList
在写入操作期间锁定整个数组。那么为什么不同呢?
如果您查看其他操作,例如遍历集合中的每个元素,就会出现差异。 Collections.synchronizedList
的文档说,
It is imperative that the user manually synchronize on the returned list when iterating over it:
List list = Collections.synchronizedList(new ArrayList());
...
synchronized (list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
Failure to follow this advice may result in non-deterministic behavior.
换句话说,迭代 synchronizedList
是不线程安全的,除非您手动锁定。请注意,使用此技术时,此列表上其他线程的所有操作(包括迭代、获取、设置、添加和删除)都将被阻止。一次只有一个线程可以对该集合执行任何操作。
相比之下,CopyOnWriteArrayList
的文档说,
The "snapshot" style iterator method uses a reference to the state of the array at the point that the iterator was created. This array never changes during the lifetime of the iterator, so interference is impossible and the iterator is guaranteed not to throw
ConcurrentModificationException
. The iterator will not reflect additions, removals, or changes to the list since the iterator was created.
此列表上其他线程的操作可以并发进行,但迭代不受任何其他线程所做更改的影响。因此,即使写操作锁定了整个列表,CopyOnWriteArrayList
仍然可以提供比普通 synchronizedList
更高的吞吐量。 (前提是读和遍历占写的比例很高。)
关于java - CopyOnWriteArrayList 和 synchronizedList 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28979488/
我正在阅读《Java 并发实践》,这个案例对我来说有点不清楚。为什么这段代码是线程安全的? @ThreadSafe public class ListHelper { public List
在为 Collections.synchronizedList 编写 putIfAbsent 方法时,需要在访问列表期间提供显式锁定。 以下代码片段更详细地解释了它: class ListHelper
我不确定如何正确使用 Collections.synchronizedList() 实现。 我有这两个: public synchronized static List getOrderList
我有一个简短的问题。如果我有一个包含读/写操作的列表: private List _persistedFilesList = Collections.synchronizedList(new Arra
我正在阅读方法 Collections.synchronizedList() 的实现并且很困惑它是装饰器模式还是代理模式的例子? 最佳答案 绝对是装饰器。它用相同接口(interface)的不同实现包
我有一个关于同步列表的一般性问题。 可以说在构造函数中我正在创建一个列表 List synchronizedList = Collections.synchronizedList(list); 我有一
这个问题在这里已经有了答案: Collections.synchronizedList and synchronized (6 个答案) 关闭 6 年前。 我正在使用 Collections.Syn
CopyOnWritearraylist 和 Collections.synchronizedList(..) 有什么区别?什么时候应该优先选择一个。 最佳答案 CopyOnWriteArrayLis
List list = Collections.synchronizedList(new ArrayList()); synchronized (list) { list.add("messa
我想知道如何在以下情况下生成数组的克隆: private List testList = Collections.synchronizedList(new ArrayList()); ... publ
在多线程应用程序中,我们有一个在单例中处理列表的方法。要获取列表的快照,我们需要执行以下操作: public List swapList() { if (syncLinkedList.isEm
java.util.Collections.SynchronizedList 中方法的实现是在互斥体上使用同步。既然所有的方法中,完整的方法体都在synchronized block 下,为什么不能写
在阅读有关集合实现的 Oracle 教程时,我发现了以下句子: If you need synchronization, a Vector will be slightly faster than a
这个问题在这里已经有了答案: Vector vs Collections.synchronizedList(ArrayList) (1 个回答) 关闭 8 年前。 我想使用集合类在多线程中添加、删除
我在 dos.oracle.com 上找到了这个 public static List synchronizedList(List list) Returns a synchronized (thre
根据我的理解,并发集合类优于同步集合,因为并发集合类不会锁定整个集合对象。相反,它们锁定了集合对象的一小部分。 但是当我检查 CopyOnWriteArrayList 的 add 方法时,我们正在获取
我正在尝试使用两个线程将 String 值添加到 ArrayList。我想要的是,当一个线程添加值时,另一个线程不应该干扰,所以我使用了 Collections.synchronizedList 方法
请参阅以下代码: List list = Collections.synchronizedList(new ArrayList()); // ... synchronized
如果我的要求规定我对列表的大部分访问都是为了阅读和修改(如果有的话),那么为什么我不能只执行以下任一操作 同步modifyList方法并使用ArrayList。对 arraylist 的所有读取都将不
我知道ArrayList不是线程安全的,我见过很多人推荐在 (Collections.synchronizedList) 中转换它。我需要创建一个系统,将 ArrayList 转换为 (Collect
我是一名优秀的程序员,十分优秀!