Java - SwingWorker - 如何在 EDT 中使用发布的数组列表

Java - SwingWorker - How to use an arraylist from publish in the EDT

访问正在另一个线程 (SwingWorker) 中处理的列表时如何避免 java.util.ConcurrentModificationException

我正在尝试使用的详细信息:

有什么问题?

当工作线程进入"fast"(停顿少于 50 毫秒)时,我经常在 paint 方法中的第 170 行遇到异常(GUI 文件称为 MotsFleches.java):

Exception in thread "AWT-EventQueue-1" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at MotsFleches.run(MotsFleches.java:170)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at org.GNOME.Accessibility.AtkWrapper.dispatchEvent(AtkWrapper.java:700)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

paint 方法中的 words 列表似乎在 EDT 处理它时被修改。我没有在那里修改它,所以它必须来自其他线程?
我认为该列表只是另一个线程中 words 列表的 "snapshot",因为它是使用 publish 方法发送的。显然不是。 那么我应该更改什么才能在 EDT 方法中使用 SwingWorker 中已发布列表的 "snapshot"?

感谢您提供的任何建议。

备注

通过发布在 SwingWorker 中创建的 words 列表并继续处理同一实例,您可以使该实例服从同步。您应该更改 doInBackground 方法来为发布创建一个新的 List,如下所示:

public List<Word> doInBackground() {
  List<Word> words = new ArrayList<Word>();
  while (!isCancelled()) {
      // do some work, define aNewWord
      words.add(aNewWord);
      publish(new ArrayList<>(words)); // don't publish words directly but create new list
      Thread.pause(someTime);
  }
  return words;
}

通过此更改,后台作业和您的绘画方法正在处理不同的对象,您的问题应该得到解决。