6

我刚刚在我的小程序中将我所有的数组移植到 ArrayList (由于我对 Java 非常缺乏知识,我不知道基本的数组类型没有任何“.add”选项),一切看起来都很好......除了不时抛出异常,但它自相矛盾:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 17, Size: 21
    at java.util.ArrayList.rangeCheck(ArrayList.java:604)
    at java.util.ArrayList.get(ArrayList.java:382)
    at guay.Puntitos.AumentarTamano(Puntitos.java:346)
    at guay.Guay$MiMouse.mouseMoved(Guay.java:226)
    at java.awt.Component.processMouseMotionEvent(Component.java:6550)
    at java.awt.Component.processEvent(Component.java:6274)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Window.processEvent(Window.java:2016)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Window.dispatchEventImpl(Window.java:2713)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:680)
    at java.awt.EventQueue$4.run(EventQueue.java:678)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Java指向我的代码块是这样的:

for (int i = 1; i < elipsasCol.size(); i++) {
  if (elipsasCol.get(i) != null && elipsasCol.get(i).contains(mouse)) {
     // This line                    
     double modulo = Math.sqrt(Math.pow(mouse.x - elipsasCol.get(i).getCenterX(), 2) 
                             + Math.pow(mouse.y - elipsasCol.get(i).getCenterY(), 2));
  }
}

该错误不会对程序的性能造成任何麻烦。但是,我很感激有人可以向我解释这个异常的原因是什么。

谢谢!

4

1 回答 1

11

这将是一个并发修改问题。这是获得该错误的唯一方法。

您没有收到并发修改错误的原因是因为您进行循环的方式不会创建迭代器,因此没有机会引发并发修改错误。

我建议在您的数组列表上同步或使用诸如CopyOnWriteArrayList之类的东西。

编辑:抱歉 CopyOnWrite 不适用于此特定问题。您需要切换到 foreach 循环才能使其成为一个选项。

针对您的以下评论:

同步:

synchronized(elipsasCol){
for (int i = 1; i < elipsasCol.size(); i++) {
  if (elipsasCol.get(i) != null && elipsasCol.get(i).contains(mouse)) {
    // This line                    
    double modulo = Math.sqrt(Math.pow(mouse.x - elipsasCol.get(i).getCenterX(), 2)
                            + Math.pow(mouse.y - elipsasCol.get(i).getCenterY(), 2));
  }
}

然后synchronized(elipsasCol){}在您触摸的其他任何地方添加类似的elipsasCol

或者

for (T obj : elipsasCol) {
  if (obj != null && obj.contains(mouse)) {
    // This line                    
    double modulo = Math.sqrt(Math.pow(mouse.x - obj.getCenterX(), 2)
                            + Math.pow(mouse.y - obj.getCenterY(), 2));
  }
}

这很可能会导致引发并发修改错误。此时,您可以将 ArrayList 切换到 CopyOnWriteArrayList 或围绕它进行同步。

于 2012-05-06T22:22:00.010 回答