JDK1.8 java.util.ConcurrentModificationException错误

一,示例代码:

List list = new ArrayList();

list.add(1);  
list.add(2);
list.add(3);
Iterator it = list.iterate(); 
while(it.hasNext()) {
    Object obj = it.next();
    list.remove(1);
}

此时绝逼会抛java.util.ConcurrentModificationException错误,怎么会呢,仔细查看JDK,原来如此

注意,此实现不是同步的。如果多个线程同时访问一个 ArrayList 实例,而其中至少一个线程从结构上修改了列表,那么它必须 保持外部同步。(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法将该列表“包装”起来。这最好在创建时完成,以防止意外对列表进行不同步的访问:
List list = Collections.synchronizedList(new ArrayList(...));
此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。

二,解决办法:

  1.  // 1 使用Iterator提供的remove方法,用于删除当前元素  
  2.  for (Iterator it = myList.iterator(); it.hasNext();) {  
  3.      String value = it.next();  
  4.       if (value.equals( "3")) {  
  5.           it.remove();  // ok  
  6.      }  
  7. }  
  8. System. out.println( "List Value:" + myList.toString());  
  9.   
  10.  // 2 建一个集合,记录需要删除的元素,之后统一删除               
  11. List templist = new ArrayList();  
  12.  for (String value : myList) {  
  13.       if (value.equals( "3")) {  
  14.           templist.remove(value);  
  15.      }  
  16. }  
  17.  // 可以查看removeAll源码,其中使用Iterator进行遍历  
  18. myList.removeAll(templist);  
  19. System. out.println( "List Value:" + myList.toString());          
  20.   
  21.   // 3. 使用线程安全CopyOnWriteArrayList进行删除操作  
  22. List myList = new CopyOnWriteArrayList();  
  23. myList.add( "1");  
  24. myList.add( "2");  
  25. myList.add( "3");  
  26. myList.add( "4");  
  27. myList.add( "5");  
  28.   
  29. Iterator it = myList.iterator();  
  30.   
  31.  while (it.hasNext()) {  
  32.      String value = it.next();  
  33.       if (value.equals( "3")) {  
  34.           myList.remove( "4");  
  35.           myList.add( "6");  
  36.           myList.add( "7");  
  37.      }  
  38. }  
  39. System. out.println( "List Value:" + myList.toString());  
  40.   
  41.  // 4. 不使用Iterator进行遍历,需要注意的是自己保证索引正常  
  42.  for ( int i = 0; i < myList.size(); i++) {  
  43.      String value = myList.get(i);  
  44.      System. out.println( "List Value:" + value);  
  45.       if (value.equals( "3")) {  
  46.           myList.remove(value);  // ok  
  47.           i--; // 因为位置发生改变,所以必须修改i的位置  
  48.      }  
  49. }  
  50. System. out.println( "List Value:" + myList.toString()); 


这里有很棒得一个总结

你可能感兴趣的:(技术总结)