猿问

并发修改具有同步列表的异常

在以下情况下,我收到并发修改异常错误。发生这种情况的行标记为“并发修改例外<--------”


我有一个主线程,从列表中读取如下:


List<ThemeCacheIndex> list = Collections.synchronizedList(themeCacheList);

synchronized (list) {

    Iterator<ThemeCacheIndex> it = list.iterator();

    while (it.hasNext()) {

        ThemeCacheIndex themeCacheIndex = it.next();  <-------- ConcurrentModificationException

        doSomething();

    }

}

我有一个从此列表中删除的异步任务:


 @Override

    protected String doInBackground(String... params) {

        someElementsToRemove = calculateWhichElementsToRemove();

        for(int i=0 ; i < someElementsToRemove.size() ; i++){

            themeCacheList.remove(someElementsToRemove.get(i));

        }

    }

我可以想象,它涉及并发情况,但我想通过在主线程上同步列表来防止这种情况。


似乎我不理解多线程和共享对象的概念。


有人可以帮助我解决这个问题吗?如何防止此冲突?


慕桂英546537
浏览 94回答 3
3回答

万千封印

异步任务代码没有问题。对“主”线程代码执行此操作:synchronized (themeCacheList) {&nbsp; &nbsp; Iterator<ThemeCacheIndex> it = themeCacheList.iterator();&nbsp; &nbsp; while (it.hasNext()) {&nbsp; &nbsp; &nbsp; &nbsp; ThemeCacheIndex themeCacheIndex = it.next();&nbsp; &nbsp; &nbsp; &nbsp; doSomething();&nbsp; &nbsp; }}如您所见,我已经删除了,因为它是多余的,我直接在 上同步。Collections.synchronizedListthemeCacheList

小唯快跑啊

不确定我有一个好的解决方案,但我想这2个例子显示了问题和可能的解决方案。“可能的重复”答案没有显示任何解决方案,而只是解释了问题所在。@Testpublic void testFails(){&nbsp; &nbsp; List<String> arr = new ArrayList<String>();&nbsp; &nbsp; arr.add("I");&nbsp; &nbsp; arr.add("hate");&nbsp; &nbsp; arr.add("the");&nbsp; &nbsp; arr.add("ConcurrentModificationException !");&nbsp; &nbsp; Iterator i = arr.iterator();&nbsp; &nbsp; arr.remove(2);&nbsp; &nbsp; while(i.hasNext()){&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(i.next());&nbsp; &nbsp; }}@Testpublic void testWorks(){&nbsp; &nbsp; List<String> arr = new CopyOnWriteArrayList<>();&nbsp; &nbsp; arr.add("I");&nbsp; &nbsp; arr.add("hate");&nbsp; &nbsp; arr.add("the");&nbsp; &nbsp; arr.add("ConcurrentModificationException !");&nbsp; &nbsp; Iterator i = arr.iterator();&nbsp; &nbsp; arr.remove(2);&nbsp; &nbsp; while(i.hasNext()){&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(i.next());&nbsp; &nbsp; }}

汪汪一只猫

引用爪哇语:Collections返回由指定列表支持的同步(线程安全)列表。为了保证串行访问,通过返回的列表完成对支持列表的所有访问至关重要。如果您修改了 ,则像您所做的那样进行同步将无济于事,因为备份列表已被修改。AsyncTaskthemeCacheList
随时随地看视频慕课网APP

相关分类

Java
我要回答