- 浏览: 73572 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
george.gu:
lqjacklee 写道怎么解决。。 First: Conf ...
Bad version number in .class file -
lqjacklee:
怎么解决。。
Bad version number in .class file -
flyqantas:
would you pleade left more mate ...
UML Extension
Where ConcurrentModificationException raised
Case 1: update value Entries during traverse Map in same Thread
java.util.ConcurrentModificationException will be raised in following java code:
Map<String, String> pendingCorrelations = new Hashtable<String, String>();
pendingCorrelations.put("a", "a1");
pendingCorrelations.put("b", "b1");
pendingCorrelations.put("c", "c1");
pendingCorrelations.put("d", "d1");
pendingCorrelations.put("e", "e1");
Set<String> keys = pendingCorrelations.keySet();
for (String key : keys) { // Here raise ConcurrentModificationException after a is removed.
if (key.equalsIgnoreCase("a")) {
pendingCorrelations.remove(key);
}
}
Exception:
java.util.ConcurrentModificationException at java.util.Hashtable$Enumerator.next(Hashtable.java:1031)
Case 2: This exception could happen in case many simultaneouse threads manipulate same value Object.
Why ConcurrentModificationException raised?
Here we focous on two points:
- How Java analyze for() element?
- What happened after Hashtable.remove(Object)?
We can image JDK will analyze for() as following:
for(String key=Hashtable$Enumerator.next();Hashtable$Enumerator.hasMoreElements();){ pendingCorrelations.remove(key); }
An interesting source code to understand well for() elements:
Map<String, String> pendingCorrelationsMap = new HashMap<String, String>(); pendingCorrelationsMap.put("c", "c1"); pendingCorrelationsMap.put("b", "b1"); pendingCorrelationsMap.put("d", "b1"); pendingCorrelationsMap.put("a", "a1"); for (String key : pendingCorrelationsMap.keySet()) { if (key.equalsIgnoreCase("a")) { // won't cause ConcurrentModificationException pendingCorrelationsMap.remove(key); } } for (String key : pendingCorrelationsMap.keySet()) { if (key.equalsIgnoreCase("c")) { // will cause ConcurrentModificationException pendingCorrelationsMap.remove(key); } }
java.util.Hashtable
/** * The number of times this Hashtable has been structurally modified * Structural modifications are those that change the number of entries in * the Hashtable or otherwise modify its internal structure (e.g., * rehash). This field is used to make iterators on Collection-views of * the Hashtable fail-fast. (See ConcurrentModificationException). */ private transient int modCount = 0; /** * The modCount value that the iterator believes that the backing * Hashtable should have. If this expectation is violated, the iterator * has detected concurrent modification. */ protected int expectedModCount = modCount; /** * Removes the key (and its corresponding value) from this * hashtable. This method does nothing if the key is not in the hashtable. * * @param key the key that needs to be removed * @return the value to which the key had been mapped in this hashtable, * or <code>null</code> if the key did not have a mapping * @throws NullPointerException if the key is <code>null</code> */ public synchronized V remove(Object key) { Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { modCount++; // Only modCount updated within Hashtable.remove(Object) if (prev != null) { prev.next = e.next; } else { tab[index] = e.next; } count--; V oldValue = e.value; e.value = null; return oldValue; } } return null; }
We can see that if any Object removed by invode Hashtable.remove(Object), only "modCount++" invoked (not expectedModCount).
java.util.Hashtable$Enumerator<T>
Hashtable$Enumberator<T>
/** * A hashtable enumerator class. This class implements both the * Enumeration and Iterator interfaces, but individual instances * can be created with the Iterator methods disabled. This is necessary * to avoid unintentionally increasing the capabilities granted a user * by passing an Enumeration. */ private class Enumerator<T> implements Enumeration<T>, Iterator<T> { ... public T next() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); return nextElement(); } public void remove() { if (!iterator) throw new UnsupportedOperationException(); if (lastReturned == null) throw new IllegalStateException("Hashtable Enumerator"); if (modCount != expectedModCount) throw new ConcurrentModificationException(); synchronized(Hashtable.this) { Entry[] tab = Hashtable.this.table; int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length; for (Entry<K,V> e = tab[index], prev = null; e != null; prev = e, e = e.next) { if (e == lastReturned) { modCount++; //both modCount and expectedModCount will be updated simultanously expectedModCount++; if (prev == null) tab[index] = e.next; else prev.next = e.next; count--; lastReturned = null; return; } } throw new ConcurrentModificationException(); } } ... }
Hashtable$Enumberator.next() will check (modCount != expectedModCount) to fast fail. Here can see how "java.util.ConcurrentModificationException" raised.
Solutions
Solution 1: Update(Remove) java collections through Iterator
As we list in prior java source code, we can see both "modCount" and "expectedCount" will be udpated simultanousely in Hashtable$Enumberator which will be return when calling Hashtable.interator().
So we can remove elements as following without ConcurrentModificationException:
Iterator iter = Collections.iterator(); while(iter.hasNext()) { iter.next(); // Iterator.next() must be called before calling remove() iter.remove(); // should be called once and only once }
Note:
- Here "Collections" is only a symbol of set of objects it is not "java.util.Collection".
- We can only invoke remove through Iterator. (because there is no other udpate operation API.)
Solution 2: Remove Objects from Collections outof Traverse Collections.
Map<String, String> pendingCorrelations = new Hashtable<String, String>(); pendingCorrelations.put("a", "a1"); pendingCorrelations.put("b", "b1"); pendingCorrelations.put("c", "c1"); pendingCorrelations.put("d", "d1"); pendingCorrelations.put("e", "e1"); Set<String> keys = pendingCorrelations.keySet(); List<String> tobeRemvoed = new ArrayList<String>(); for (String key : keys) { if (key.equalsIgnoreCase("a")) { tobeRemvoed.add(key); // pendingCorrelations.remove(key); } } assertEquals(5, pendingCorrelations.size()); for (String str : tobeRemvoed) { pendingCorrelations.remove(str); } assertEquals(4, pendingCorrelations.size());
发表评论
-
javax.naming.CommunicationException: remote side declared peer gone on this JVM.
2012-07-11 09:44 2379javax.naming.ServiceUnavailable ... -
Generate special format numbers
2012-04-27 00:06 940DecimalFormat df = new DecimalF ... -
Scheduled ThreadPool Executor suppressed or stopped after error happen
2012-03-20 16:54 1044ScheduledThreadPoolExecutor ... -
Memory Leak analyze
2012-03-12 06:21 926Shallow Heap Size Shallow siz ... -
Scalable and Easy to Integrate (3): Share Data with external Server by LDAP
2012-02-28 05:25 0Share Data with external Server ... -
Scalable and Easy to Integrate (2): Linstener
2012-02-28 05:20 0descript listener pattern in pr ... -
Scalable and Easy to Integrate (1): Callback
2012-02-28 05:19 0Descript the callback method de ... -
Wheels: Common utilities reuse and design
2012-02-18 05:57 836Search-->Copy-->Small ... -
Java Exception Design
2012-02-18 05:36 845Talk something used to happen i ... -
JMX in Weblogic
2012-02-17 19:20 1655Here I would like to list some ... -
Java String Charset Encoding
2012-02-09 00:28 3024Charset Charset is a named map ... -
Weblogic 11g JSP cache
2012-01-31 00:41 2892Normally, jsp_servlet classes ... -
2011,这样走过!
2011-12-31 06:01 101月11日,琪琪从巴黎 ... -
Security Manager
2011-12-20 21:20 0http://journals.ecs.soton.ac ... -
Unique Identifier generation in Java Application
2011-12-23 06:17 740During application design, ther ... -
WorkManager in Weblogic and Multiple Thread design in Enterprise Application
2011-12-15 05:25 0Descrip how to use workmanager ... -
AOP(3): Spring AOP
2011-12-20 05:24 1015AOP References Please refe ... -
JMX Usage
2011-12-13 06:22 830There is long times since last ... -
Using Taglib to Implement Dynamic UI
2011-12-12 06:13 952What's Taglib? Taglib is a JSP ... -
EJB: Singleton in EJB
2011-12-06 00:58 0When I was using EJB to impleme ...
相关推荐
Java.util.ConcurrentModificationException 异常问题详解 ConcurrentModificationException 异常是 Java 中一个常见的异常,它发生在 Iterator 遍历集合时,集合同时被修改引起的异常。在 Java 中,集合类如 ...
在Java编程中,`java.util.ConcurrentModificationException` 是一个常见的运行时异常,通常发生在尝试并发修改集合时。这个异常的产生是由于集合类(如HashMap)的非线程安全特性,当你在一个线程中使用迭代器遍历...
`java.util.ConcurrentModificationException` 是一个在 Java 中常见的运行时异常,它通常发生在多线程环境中,当一个线程正在遍历一个集合(如 `ArrayList`, `HashMap` 等),而另一个线程同时尝试修改这个集合时。...
常见问题
在Java编程中,`ConcurrentModificationException`是一个常见的运行时异常,主要出现在多线程环境下对集合类(如List、Set、Map等)进行并发修改时。然而,这个异常不仅限于多线程环境,即使在单线程中,如果在遍历...
Java语言的Util类详细介绍 Java语言的Util类是Java开发中非常重要的一部分,它提供了一系列的类来实现基本的数据结构,如线性表、链表等。这些类均在java.util包中。 Collection接口是Java中最基本的集合接口,一...
Spring数据mongodb测试 在Collections.synchronizedList或Collections.synchronizedSet上测试spring数据mongodb ConcurrentModificationException
java.util.ConcurrentModificationException: mutation occurred during iteration [error] scala.collection.mutable.MutationTracker$.checkMutations(MutationTracker.scala:43) [error] scala.collection....
使用`synchronized`关键字、`volatile`变量、`java.util.concurrent`包中的工具类等可以有效地管理并发。 四、内存泄漏 Java中的内存泄漏并不像C++那样直接导致资源耗尽,但过度持有对象引用会导致垃圾收集器无法...
否则将会引发 java.util.ConcurrentModificationException 异常。 3. Iterator 迭代器采用的是快速失败(fail-fast)机制,一旦在迭代过程中检测到该集合已经被修改(通常是程序中其它线程修改),程序立即引发 ...
- `java.util.Iterator`的改进:支持`remove()`操作,避免抛出`ConcurrentModificationException`。 ### 4. 性能优化 JDK 1.6对编译器和垃圾收集器进行了优化,提高了运行效率,例如: - **Server VM的改进**: ...
需要注意的是,在迭代的过程中不能对集合中元素进行修改,否则将产生 java.util.ConcurrentModificationException。 选择集合 在实际开发中,选择合适的集合是非常重要的。以下是一些选择集合的建议: * 如果需要...
import java.util.ArrayList; import java.util.Iterator; public class IteratorExample { public static void main(String[] args) { ArrayList<String> names = new ArrayList(); names.add("Ada Lovelace");...
Java的`java.util.concurrent`包提供了更为高效且专门设计用于并发操作的集合。比如: - `ConcurrentHashMap`:线程安全的哈希映射,比`synchronized Map`性能更好,因为它允许不同部分独立加锁,减少了锁竞争。 ...
4. 如果需要更复杂的并发控制,可以使用`java.util.concurrent.locks`包下的Lock接口及其实现,如ReentrantLock,配合`tryLock()`方法进行细粒度的锁控制。 总的来说,处理多线程环境中的Java集合类时,开发者需要...
java中,List在遍历的时候,如果被修改了会抛出java.util.ConcurrentModificationException错误。 看如下代码: import java.util.ArrayList; import java.util.List; public class Resource3 { public ...
在Java编程语言中,集合框架(`java.util`包)提供了多种容器类来存储对象,如`List`、`Set`和`Map`等。为了遍历这些容器中的元素,Java引入了迭代器模式(Iterator Pattern),这是一种常用的设计模式,它提供了一...