黑马程序员技术交流社区

标题: 并发异常产生的异常原因以及解决方案问题得积累 [打印本页]

作者: ImKing    时间: 2016-7-9 12:05
标题: 并发异常产生的异常原因以及解决方案问题得积累
        记得以前回复过一个相关的问题,是在完成相关视频之前,本来是想找一下回复修改过来的,不过没找到帖子,,,,
        这里贴出相关理论知识吧(有必要掌握),下次见到的话,有机会帮助修改过来。
问题描述:
  1. List list = new ArrayList();
  2.             list.add("a");
  3.             list.add("b");
  4.             list.add("world");
  5.             list.add("d");
  6.             list.add("e");
  7.             
  8. Iterator it = list.iterator();
  9.             while(it.hasNext()) {
  10.         String str = (String)it.next();
  11.         if(str.equals("world")) {
  12.                list.add("javaee");   //这里会抛出ConcurrentModificationException并发修改异常,遍历的同时,在增加元素。并发修改
  13.         }
  14.             }
复制代码
(刚开始很容易想到这样实现,,,)

解决方案:

  1. ListIterator lit = list.listIterator();        //如果想在遍历的过程中添加元素,可以用ListIterator中的add方法
  2.             while(lit.hasNext()) {
  3.         String str = (String)lit.next();
  4.         if(str.equals("world")) {
  5.                 lit.add("javaee");   
  6.         }
  7.             }
复制代码




作者: 勿忘`初心    时间: 2016-7-9 12:12
底层原理是什么呢?这些有点懵逼
作者: ImKing    时间: 2016-7-9 12:14
勿忘`初心 发表于 2016-7-9 12:12
底层原理是什么呢?这些有点懵逼

建议,先记着怎么用,等熟练了再往深层次研究。
不然很容易搞混,建议逐层深入 {:3_56:}
作者: 我是你岁哥❤环    时间: 2016-7-9 13:11
本帖最后由 我是你岁哥❤环 于 2016-7-9 13:12 编辑

并发修改异常  ConcurrentModificationException, 这个异常时迭代器对象抛出的,出现的原因是集合中增加了元素到会迭代器预期的迭代次数发生改变,导致迭代器的结果不准确.另外一种解决方式:
从业务逻辑上讲,我们只要找到 "world" 这个元素,至于后面还有多少个元素我们并不关心,所以只需要找到这个元素后跳出循环不在迭代即可
  1. Iterator it = list.iterator();
  2. while(it.hasNext()) {
  3.         String str = (String)it.next();
  4.         if(str.equals("world")) {
  5.                list.add("javaee");  
  6.                break;
  7.         }
  8. }
复制代码
在使用break语句跳出循环后,由于没有继续使用迭代器对集合中的元素进行迭代,因此,集合中增加的元素对程序没有任何影响,不会出现异常



作者: cat73    时间: 2016-7-9 13:26
本帖最后由 cat73 于 2016-7-9 13:36 编辑
我是你岁哥❤环 发表于 2016-7-9 13:11
并发修改异常  ConcurrentModificationException, 这个异常时迭代器对象抛出的,出现的原因是集合中增加了元 ...

我认为不同逻辑还是分离的好

一块代码专门负责找 world,如果找到则设置 found = true

下面的代码再去根据这个 found 去进行后续的修改

  1.     private void test() {
  2.         List<String> list = new ArrayList<>();
  3.         list.add("a");
  4.         list.add("b");
  5.         list.add("world");
  6.         list.add("d");
  7.         list.add("e");
  8.         
  9.         if (equalsContains(list, "world")) {
  10.             list.add("javaee");
  11.         }
  12.     }
  13.    
  14.     private <T> boolean equalsContains(Collection<T> collection, T t) {
  15.         for(T t2 : collection) {
  16.             if(t.equals(t2)) {
  17.                 return true;
  18.             }
  19.         }
  20.         return false;
  21.     }
复制代码

作者: ImKing    时间: 2016-7-9 14:07
我是你岁哥❤环 发表于 2016-7-9 13:11
并发修改异常  ConcurrentModificationException, 这个异常时迭代器对象抛出的,出现的原因是集合中增加了元 ...

那么开发中比较常用的是那种方式呢?
(1)List、Break结合
(2)使用 ListIterator(ListIterator)
(3)求指导{:3_56:}




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2