在多线程程序中抛出ConcurrentModificationException

时间:2016-01-30 22:37:38

标签: java multithreading loops synchronization locking

我正在尝试模拟一个程序,该程序模拟在ArrayList中删除和添加对象的不同线程。但是,在模拟的后期我得到concurrentModificationExceptions(当线程试图访问和修改同一个变量时,迭代器被用来迭代数据)。我已经搜索过了,并且看到了一些关于这个问题的话题,我需要使用锁/同步和/或使用ListIterators而不是增强的for循环,但是,这些选项似乎都无法解决问题。以下是我到目前为止所做的尝试:

public Object removeSomething1(){
    synchronized(this){ //Also tried only putting it around the remove block
        for(Object o : myList){
            myList.remove(o);
            return o;
        }
    }

}

//This is another variaton which did not yield any improved result

public Object removeSomething2(){
    ListIterator<Object> iter = myList.listIterator();
        While(iter.hasNext()){
            Object s = iter.next();
            synchronized(this){
                iter.remove();

            }
            return s;

        }

    }

//After some request here is also the simple code which adds to the list

public addSomething(Object o){
    myList.add(o);
}

我执行了5个线程,它们在run()方法中以500ms的间隔调用这些方法(使用Thread.sleep())。如果我在每个线程中增加睡眠定时器并在线程的每个实例之间放置一个Thread.sleep(),问题似乎就会消失,但我希望线程在(紧密)同时运行而不会干扰迭代器在同时调用ConcurrentModificationException。

1 个答案:

答案 0 :(得分:-2)

根据用户Louis Wasserman的建议,我移动synchronized块以包含所有removeSomething2()。这是有道理的,因为它现在只允许一个线程一次完成整个迭代。这就是解决方案的外观:

public Object removeSomething2(){
synchronized(this){
    ListIterator<Object> iter = myList.listIterator();
        While(iter.hasNext()){
            Object s = iter.next();
            iter.remove();
            return s;
        }
    }
}