ConcurrentModificationException与全局变量但不是局部变量局部变量

时间:2012-11-10 13:38:11

标签: java global-variables local-variables concurrentmodification

在下面的函数中,我声明了局部变量allPeopelitr(它们覆盖了全局变量)。如果我注释掉局部变量(在下面的Astrixes之间),则抛出ConcurrentModificationError。但是,如果我使用局部变量而不是全局变量,那么代码工作正常。我不明白为什么会这样?该类中还有许多其他函数,因此我尝试使用全局变量来获得更高效的代码。

   public void removeAPerson(){
        int id;
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter ID of person to delete > ");
        id = sc.nextInt();
        sc.nextLine();
        System.out.println();

        /*************************************/
        ArrayList<Person> allPeople;
        allPeople = Person.getAllPeople();
        Iterator itr = allPeople.iterator();
        /*************************************/

        while(itr.hasNext()){
            Person obj = (Person) itr.next();
            int ID = obj.getID2();
            if(ID == id){
                itr.remove();
                break;
            }
        }
    }

2 个答案:

答案 0 :(得分:2)

这是你可能拥有的草图:

public class MyClass {
  List<Person> persons = new ArrayList<>();
  Iterator<Person> iter = strs.iterator();

  public void addPerson(Person p) {
    persons.add(p);
  }

  public void removePerson() {
    ... your posted code ...
  }


  public static void main(String... args) {
    MyClass c = new MyClass();
    c.addPerson(new Person());
    c.removePerson();
  }

只会将迭代器实例化一次,然后向列表添加内容,然后使用迭代器。重用像这样的迭代器的全局实例永远不会有意义。具体来说,在实例化之后,除非通过迭代器本身,否则不得更改列表。

使用全局变量是一回事,但使用迭代器的全局实例是另一回事。两者都是错的,但后者是致命的。

答案 1 :(得分:0)

使用局部变量,每次线程调用您的方法时都会创建这些变量的新实例,这些变量不可用于任何其他线程(除非您特别允许传递引用)。因此,没有其他线程可以修改您的对象。

使用全局(我认为你的意思是instance变量,属性),所有有权访问你对象的线程都可以访问对象的那些属性(让它直接使用,让它运行你的对象方法)并且可以在其他线程运行迭代时修改它们。由于iterator可以检测到正在迭代的Collection何时被修改,当发生这种情况时它会抛出异常(这意味着没有别的“我正在迭代集合的所有对象但是这些对象不再相同,所以这太混乱了,我失败了。“