简体   繁体   English

Collection.size()可以抛出ConcurrentModificationException吗?

[英]Can Collection.size() throw ConcurrentModificationException?

As we all know, iterating without synchronization on a collection risks throwing ConcurrentModificationException if another thread happens to concurrently modify the collection. 众所周知,如果另一个线程碰巧同时修改了集合,则在不同步集合的情况下进行迭代有引发ConcurrentModificationException风险。

But what about calling size() on the collection? 但是在集合上调用size()呢? Does size() involve iteration to count the number of elements in the collection? size()是否涉及迭代以计算集合中元素的数量? If that is the case, ConcurrentModificationException may occur (some people report this, for example here , but for me it is not clear that size() was the culprit). 如果是这种情况,可能会发生ConcurrentModificationException (例如,有人在此处报告此情况,但对我来说,不清楚size()是罪魁祸首)。

On the other hand, if size() just gets an internal int counter variable, no exception would occur. 另一方面,如果size()仅获得一个内部int计数器变量,则不会发生异常。

Which one is the case? 是哪种情况?

HUMBLE EDIT: Thanks to the answerers for the precision that this depends on the implementation. 拙劣的编辑:感谢答复者提供的精度,这取决于实现。 I should have mentioned that it is a TreeMap. 我应该提到这是一个TreeMap。 Can I have this problem with that map? 我可以在地图上遇到这个问题吗? The docs say nothing about TreeMap.size(). 该文档没有提到TreeMap.size()。

The docs don't explicitly state that a ConcurrentModificationException will occur if you invoke Collection#size . 文档未明确声明如果调用Collection#size则会发生ConcurrentModificationException

The only real times it's thrown are described in ConcurrentModificationException itself : 抛出的唯一实时信息ConcurrentModificationException本身中进行了描述

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible. 当不允许对对象进行同时修改时,检测到该对象的同时修改的方法可能会引发此异常。

For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. 例如,通常不允许一个线程修改Collection而另一个线程对其进行迭代。 In general, the results of the iteration are undefined under these circumstances. 通常,在这些情况下,迭代的结果是不确定的。 Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. 如果检测到此行为,则某些Iterator实现(包括JRE提供的所有通用集合实现的实现)可能会选择抛出此异常。 Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future. 执行此操作的迭代器称为快速失败迭代器,因为它们会快速干净地失败,而不是在未来的不确定时间内冒任意,不确定的行为的风险。

If you're really worried about this sort of thing, then be sure that the concrete implementation of your collection uses an approriate size() method, like ConcurrentLinkedQueue . 如果您真的担心这种事情,请确保集合的具体实现使用适当的size()方法,例如ConcurrentLinkedQueue

Returns the number of elements in this queue. 返回此队列中的元素数。 If this queue contains more than Integer.MAX_VALUE elements, returns Integer.MAX_VALUE. 如果此队列包含多个Integer.MAX_VALUE元素,则返回Integer.MAX_VALUE。 Beware that, unlike in most collections, this method is NOT a constant-time operation. 注意,与大多数集合不同,此方法不是恒定时间操作。 Because of the asynchronous nature of these queues, determining the current number of elements requires an O(n) traversal. 由于这些队列的异步性质,确定当前元素数需要进行O(n)遍历。

Additionally, if elements are added or removed during execution of this method, the returned result may be inaccurate. 此外,如果在执行此方法期间添加或删除了元素,则返回的结果可能不准确。 Thus, this method is typically not very useful in concurrent applications. 因此,此方法在并发应用程序中通常不是很有用。

It doesn't matter whether size() will throw ConcurrentModificationException . size()是否会引发ConcurrentModificationException无关紧要。 Almost no collections will throw that exception on size() , but that doesn't make it safe. 几乎没有集合会在size()上抛出该异常,但这并不安全。

When you call size() on a collection that other threads modify, you're reading shared memory. 在其他线程修改的集合上调用size()时,您正在读取共享内存。 If the collection you're using doesn't offer specific synchronization guarantees and you're not using other synchronization mechanisms, the value you read could be arbitrarily out of date, or it could even correspond to a program state that you would think "hasn't happened yet". 如果您使用的集合没有提供特定的同步保证,并且您没有使用其他同步机制,则读取的值可能是任意过期的,甚至可能对应于您认为“已经存在”的程序状态。还没发生”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以使用Collection.size()替换此代码中的计数器吗? - Can I use Collection.size() to replace the counter in this code? 将带有collection.size的hibernate HQL转换为条件查询 - Convert hibernate HQL with collection.size to criteria query 如何在jstl中创建等效的for(int i = 0,i &lt;= collection.size()+ 1,i ++) - how to create equivalent for(int i=0, i<= collection.size() + 1, i++) in jstl 单核处理器还能抛出 ConcurrentModificationException 吗? - Can a single core processor still throw ConcurrentModificationException? Java迭代器如何检测集合被修改抛出ConcurrentModificationException? - How Java iterators detect the collection is modified to throw ConcurrentModificationException? 除了ConcurrentModificationException之外,此代码还能引发其他任何异常吗? - Can this code throw any other exception than ConcurrentModificationException? 创建引用可以在带有 objectify 的事务内引发 ConcurrentModificationException - Creating a reference can throw a ConcurrentModificationException inside of a transaction with objectify 循环迭代器Java抛出ConcurrentModificationException - Looping Iterator Java throw ConcurrentModificationException 为什么这段代码会引发ConcurrentModificationException? - Why does this code throw ConcurrentModificationException? 为什么这段代码不抛出 ConcurrentModificationException? - Why does this code NOT throw a ConcurrentModificationException?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM