门户网站首页,wordpress后台分类添加图片,金融电子商务网站建设,橘子建站是什么今天在写一个带缓存功能的访问代理程序时出现了java.util.ConcurrentModificationException异常#xff0c; 因为该异常是非捕获型异常而且很少见#xff0c;所以费了些时间才找到问题所在#xff0c;原来在通过Iterator进行遍历的时候#xff0c;如果直接对HashMap进行操作…今天在写一个带缓存功能的访问代理程序时出现了java.util.ConcurrentModificationException异常 因为该异常是非捕获型异常而且很少见所以费了些时间才找到问题所在原来在通过Iterator进行遍历的时候如果直接对HashMap进行操作后再继续用之前的Iterator进行遍历就会出现这个异常表示其HashMap已经被修改。 源程序代码片段如下caches为一个HashMap对象 1 String sameKeyPart accesserClassName methodName parameterKeyString ;
2 Iterator keys caches.keySet().iterator();
3 String key null;
4 while (keys.hasNext()) ...{
5 key (String) keys.next();
6 if (key.startsWith(sameKeyPart)) ...{
7 caches.remove(key);
8 }
9 } 解决办法为通过其相应的Iterator进行删除就可以了修改后代码片段如下 1 String sameKeyPart accesserClassName methodName parameterKeyString ;
2 Iterator keys caches.keySet().iterator();
3 String key null;
4 while (keys.hasNext()) ...{
5 key (String) keys.next();
6 if (key.startsWith(sameKeyPart)) ...{
7 keys.remove();
8 }
9 } 2、 撰写多线程代码时你遇到过多少次下面的提示Exception in thread main java.util.ConcurrentModificationException 这个异常产生的原因有几个。一是直接对集合调用删除操作而不是在枚举器上。二是不同的线程试图对集合进行增删操作的时候。 这个解决办法的第一步就是同步代码使得你在枚举的时候其它的线程不能增删记录。但是如果每个枚举过程要进行复杂的计算或者是数据库访问的一部分的话这个同步就会导致可怕的后果。为了减少负面影响可以拷贝一个只读的枚举器去掉同步然后采用下列代码所示的方法 1 private List list;2 public void add(Object obj) {3 synchronized(list) {4 list.add(obj);5 }6 }7 public void perform( ) {8 Iterator iterator null;9 synchronized(list) {
10 iterator new CopiedIterator(list.iterator( ));
11 }
12 while(iterator.hasNext( )) {
13 // perform resource or cpu hungry work
14 }
15 } 重要的是记住CopiedIterator不是一个克隆只是一个只读的拷贝所以它并没有保持原有的全部功能。最重要的是不能再调用CopiedIterator.remove方法了。CopiedIterator.remove的实现如下 1 public class CopiedIterator implements Iterator {2 private Iterator iterator null;3 public CopiedIterator(Iterator itr) {4 LinkedList list new LinkedList( );5 while(itr.hasNext( )) {6 list.add(itr.next( ));7 }8 this.iterator list.iterator( );9 }
10 public boolean hasNext( ) {
11 return this.iterator.hasNext( );
12 }
13 public void remove( ) {
14 throw new UnsupportedOperationException(This is a read-only iterator.
15 );
16 }
17 public Object next( ) {
18 return this.iterator.next( );
19 }
20 } 枚举器的只读拷贝将用在同步状态上的时间减少到最小因此可以增强全局的效率。 3、 当使用 fail-fast iterator 对 Collection 或 Map 进行迭代操作过程中尝试直接修改 Collection / Map 的内容时即使是在单线程下运行 java.util.ConcurrentModificationException 异常也将被抛出。 Iterator 是工作在一个独立的线程中并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表当原来的对象数量发生变化时这个索引表的内容不会同步改变所以当索引指针往后移动的时候就找不到要迭代的对象所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。 所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象 Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。 有意思的是如果你的 Collection / Map 对象实际只有一个元素的时候 ConcurrentModificationException 异常并不会被抛出。这也就是为什么在 javadoc 里面指出 it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs. 1 import java.util.*; 2 3 public final class MyTest 4 { 5 private static HashMap p_mapList new HashMap(2); 6 private MyTest(){} 7 public static void init(){ 8 // If only there are more than one element in Map, 9 // the ConcurrentModificationException will not be 10 // thrown. 11 p_mapList.put(new String(hello),new String(world)); 12 p_mapList.put(new String(goto),new String(hell)); 13 } 14 public static void clear() throws Exception{ 15 Iterator pTmpKeys null; 16 Long pTmpKeyLong; 17 pTmpKeys p_mapList.keySet().iterator(); 18 String pCurKey null; 19 String pCurObj null; 20 while(pTmpKeys.hasNext()){ 21 pCurKey (String) pTmpKeys.next(); 22 pCurObj (String) p_mapList.get(pCurKey); 23 24 p_mapList.put(pCurKey,null); 25 // You can not remove element in Map object directly. 26 //p_mapList.remove(pCurKey); 27 // But you can remove current element by iterator itself. 28 pTmpKeys.remove(); 29 30 System.out.println(pCurKey removed.); 31 } 32 System.out.println(p_mapList.size() 33 entries left after iterator.); 34 pTmpKeys null; 35 } 36 public static void main(String[] args) 37 throws Exception{ 38 MyTest.init(); 39 MyTest.clear(); 40 } 41 } 转载于:https://www.cnblogs.com/wslcs/p/4978233.html