ArrayList<Integer> contents = new ArrayList<>();for (int i = 0; i < 100; i++) {contents.add(i);}new Thread(()->{Iterator<Integer> iterator = contents.iterator();System.out.println(Thread.currentThread().getName()+"::");while (iterator.hasNext()) {Integer next = iterator.next();//contents.remove(next);System.out.print(next);}System.out.println();},"线程1").start();new Thread(()->{Iterator<Integer> iterator = contents.iterator();System.out.println(Thread.currentThread().getName()+"::");while (iterator.hasNext()) {Integer next = iterator.next();if (next%2==0) {//contents.remove(next);System.out.print(next);iterator.remove();}}},"线程2").start();
线程1::0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,线程2::0,2,4,6,8,46,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,Exception in thread "线程1" java.util.ConcurrentModificationExceptionat java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)at java.util.ArrayList$Itr.next(ArrayList.java:859)at com.company.Main.lambda$main$0(Main.java:312)at java.lang.Thread.run(Thread.java:748)
上篇我们分析了ConcurrentModificationException异常是因为expectedModCount和modCount不相等导致。我们知道modCount是AbstarctList的成员变量,expectedModCount是迭代器对象的私有变量。也就是说线程1,和线程2都可以改变共有的modCount,而线程1,和线程2各自的迭代器对象中的expectedModCount是不同的。在我们上面的测试代码中,线程2修改了集合,线程1没有修改,因此,当线程2执行完,切换到线程1的时候,线程1的迭代器对象的expectedModCount肯定和modCount是不想等的,因此报出异常。
那么我们怎么解决多线程下的这个问题呢?当然是线程同步。下面我们改造下代码,当然线程同步的方式有很多,synchronized,Lock等等,这里我们使用synchronized。代码如下:
ArrayList<Integer> contents = new ArrayList<>();for (int i = 0; i < 100; i++) {contents.add(i);}//创建同步对象Object o = new Object();new Thread(() -> {synchronized (o) {Iterator<Integer> iterator = contents.iterator();System.out.println(Thread.currentThread().getName());while (iterator.hasNext()) {Integer next = iterator.next();//contents.remove(next);System.out.print(next+",");}}},"线程1").start();new Thread(() -> {synchronized (o) {Iterator<Integer> iterator = contents.iterator();System.out.println(Thread.currentThread().getName());while (iterator.hasNext()) {Integer next = iterator.next();if (next%2==0) {//contents.remove(next);iterator.remove();}}System.out.println(contents);}},"线程2").start();
线程2[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]线程11,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,Process finished with exit code 0
文章转载自Serenest Person,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




