Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-SwingWorker-如何使用EDT中发布的arraylist_Java_User Interface_Arraylist_Swingworker - Fatal编程技术网

Java-SwingWorker-如何使用EDT中发布的arraylist

Java-SwingWorker-如何使用EDT中发布的arraylist,java,user-interface,arraylist,swingworker,Java,User Interface,Arraylist,Swingworker,在访问另一个线程(SwingWorker)中正在处理的列表时,如何避免java.util.ConcurrentModificationException 有关我尝试使用的内容的详细信息: 一个包含这个“main”方法的GUI类,我认为应该在EDT上运行 public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() {

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

有关我尝试使用的内容的详细信息:
  • 一个包含这个“main”方法的GUI类,我认为应该在EDT上运行

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new myGUIwithButton();
            }
        });
    }
    
  • 此GUI有一个绘制方法,它获取
    单词列表
    ,一个包含字符串和坐标的类,并显示它们:

    public void paint(final List<Word> words){
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // prepare GUI's background, then :
                for(Word word : words){ // <-- this is line 170 in the error shown below
                    // show each word in the GUI
                    // note that I'm not modifying the words list here
                }
    
  • 然后,发布的单词将自动发送到覆盖的
    过程
    方法:

    protected void process(List< List<Word> > wordss) { // Executed on EDT ! <3
        // I'm taking only the first list that was published to avoid trouble
        List<Word> words = wordss.get(0); 
        myGUI.paint(words);
    }
    
    EDT正在处理
    绘制
    方法中的
    单词
    列表时,该列表似乎正在被修改。我没有在那里修改它,所以它必须来自另一个线程?
    我认为这个列表只是另一个线程中
    单词
    列表的“快照”,因为它是通过
    publish
    方法发送的。显然不是。 那么,在EDT方法中使用
    SwingWorker
    中发布的列表的“快照”时,我应该做哪些更改?

    谢谢你提供的任何建议

    笔记
    • 异常发生后,程序将继续正常运行。我只想把它弄干净
    • 我试图查看甚至
      synchronized(words){…}
      ,但我所有的尝试都失败了,很可能是因为我不知道“synchronizem”在本例中的含义以及如何使用它
    • 注意,paint方法中的
      invokeLater
      一开始似乎没用,因为我总是从EDT调用它,但是如果我不使用它,
      paint
      的第一次调用在GUI创建时不起作用(是不是因为它在GUI之前执行,尽管在GUI之后被调用
    • 我显然缺乏很多概念,所以细节将非常感谢

    通过发布SwingWorker中创建的
    单词
    列表并继续在同一实例上工作,您可以使此实例受到同步。您应该更改
    doInBackground
    方法,为发布创建新的
    列表
    ,如下所示:

    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;
    }
    
    公共列表doInBackground(){
    List words=new ArrayList();
    而(!isCancelled()){
    //做一些工作,定义一个世界
    添加(aneword);
    publish(newarraylist(words));//不直接发布单词,而是创建新列表
    暂停(某个时候);
    }
    返回单词;
    }
    

    通过此更改,背景工作和绘制方法正在处理不同的对象,您的问题应该得到解决。

    要提出具体的建议有些困难,因为代码片段是零碎的,我们必须将其拼凑在我们的头脑中。如果您能提供一个简单的解决方案,那么就更容易了。至于问题:您正在使用相同的到处引用列表,这就是为什么会出现异常。作为第一步,要创建快照,只需在
    doInBackground
    中手动创建一个新列表,并将其传递到
    publish
    。看看这是否有帮助。我知道使用“SSCCE”会更好,但是我觉得自己没有能力做到这一点,因为重现问题需要SwingWorker执行一项“长”任务,在此期间它会更改列表,因此我认为我无法暂停模拟它。无论如何,幸运的是,我的问题出在我选择的几行代码中。:)它可以工作,谢谢!我简直不敢相信我离解决这个问题这么近:在提出问题之前,我试着用画法创建一个副本,但没有成功。这很奇怪,因为我刚刚试过,它也解决了问题。我第一次一定是做错了。在paint中创建一个新列表不会起作用,至于创建新列表,您也需要迭代到旧列表。它可能会降低问题发生的可能性,但您会不时遇到异常。实际上,这就是并发性成为编程中最困难的方面之一的原因。仅仅通过多次执行您的代码,您不能说:我确信它是有效的。您需要了解线程可以采取的不同路径,并始终假设最坏的情况。
    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$2.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.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.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$5.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)
    
    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;
    }