Enumeration不扔ConcurrentModificationException,为什么?
见下面的代码.
public static void main(String[] args) {
Vector<String> v=new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
v.add("Sumit");
v.add("Aron");
v.add("Trek");
Enumeration<String> en=v.elements();
while(en.hasMoreElements())
{
String value=(String) en.nextElement();
System.out.println(value);
v.remove(value);
}
}
Run Code Online (Sandbox Code Playgroud)
它只打印:
Amit Pathak Aron
为什么会出现这种情况.我们可以说这Enumerator是线程安全的吗?
编辑:使用Iterator时,它会抛出ConcurrentModificationException单线程应用程序.
public static void main(String[] args) {
Vector<String> v=new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
v.add("Sumit");
v.add("Aron");
v.add("Trek");
Iterator<String> it=v.iterator();
while(it.hasNext())
{
String value=(String) it.next();
System.out.println(value);
v.remove(value);
}
}
Run Code Online (Sandbox Code Playgroud)
请检查.
sfu*_*ger 12
请注意,ConcurrentModificationException与多线程或线程安全意义上的并发性无关.有些集合允许并发修改,有些则不允许.通常,您可以在文档中找到答案.但并发并不意味着不同的线程同时发生.这意味着您可以在迭代时修改集合.
ConcurrentHashMap是一种特殊情况,因为它在迭代时被明确定义为线程安全且可编辑(我认为对于所有线程安全集合都是如此).
无论如何,只要您使用单个线程来迭代和修改集合,ConcurrentHashMap就是您的问题的错误解决方案.您错误地使用了API.您应该使用Iterator.remove()来删除项目.或者,您可以在迭代和修改原始文件之前复制该集合.
编辑:
我不知道任何抛出ConcurrentModificationException的Enumeration.但是,并发修改时的行为可能与您预期的不同.正如您在示例中看到的,枚举会跳过列表中的每个第二个元素.这是因为它的内部索引随着删除而递增.所以这就是:
Iterator的快速失败行为可以保护您免受此类事件的影响,这就是为什么它通常比Enumberation更好.相反,您应该执行以下操作:
Iterator<String> it=v.iterator();
while(it.hasNext())
{
String value=(String) it.next();
System.out.println(value);
it.remove(); // not v.remove(value); !!
}
Run Code Online (Sandbox Code Playgroud)
或者:
for(String value : new Vector<String>(v)) // make a copy
{
String value=(String) it.next();
System.out.println(value);
v.remove(value);
}
Run Code Online (Sandbox Code Playgroud)
第一个肯定是可取的,因为只要您按照预期使用API,您就不需要副本.
枚举不会抛出 ConcurrentModificationException ,为什么?
因为正在调用的代码中没有抛出此异常的路径。编辑:我指的是 Vector 类提供的实现,而不是一般的 Enumeration 接口。
为什么会出现这样的行为。我们可以说 Enumerator 是线程安全的吗?
从某种意义上说,它是线程安全的,执行的代码是正确同步的。然而,我不认为你的循环产生的结果是你想要的。
输出的原因是 Enumeration 对象维护一个计数器,该计数器在每次调用 后都会递增nextElement()。该计数器不知道您对 的调用remove()。
| 归档时间: |
|
| 查看次数: |
28837 次 |
| 最近记录: |