Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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';s done方法甚至在doInBackground完成之前随机执行_Java_Multithreading_Swing_Swingworker - Fatal编程技术网

Java SwingWorker';s done方法甚至在doInBackground完成之前随机执行

Java SwingWorker';s done方法甚至在doInBackground完成之前随机执行,java,multithreading,swing,swingworker,Java,Multithreading,Swing,Swingworker,我有一段JFrame代码,当一个SwingWorker关闭时,它会停止: import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.SwingWorker; import javax.swing.WindowConstants; /** * * @author yccheok */ public class Ja

我有一段
JFrame
代码,当一个
SwingWorker
关闭时,它会停止:

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;

/**
 *
 * @author yccheok
 */
public class JavaApplication11 extends JFrame {

    public JavaApplication11() {
        this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        final Task task = new Task();
        task.execute();
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                if (task != null) {
                    task.cancel(true);
                }
            }           
        }); 
    }

    public class Task extends SwingWorker<Void, Void> {

        @Override
        protected Void doInBackground() {
            for (int i = 0; i < 1000; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    System.out.println("interrupted in doInBackground");
                    break;
                }
                System.out.println("-> " + i);
            }
            return null;
        }

        @Override
        public void done() {
            System.out.println("DONE!!!");
        }        
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new JavaApplication11().setVisible(true);
    }
}
我可以知道为什么吗?

从Howard的评论来看,这可能是一个bug

我也遇到过这个问题。我倾向于将清理放在
doInBackground
中,如果它依赖于顺序,则只使用
done
进行异常处理

@Override
protected Void doInBackground() {
    try {
        // ...
    } finally {
        // some cleanup inside 'doInBackground'
        if (isCancelled()) {
            // ...
        } else {
            // ...
        }
    }
    return (Void) null;
}
@Override
protected void done() {
    try {
        get();
    } catch (CancellationException x) {
        // ...
    } catch (InterruptedException x) {
        // ...
    } catch (ExecutionException x) {
        // ...
    }
}
(如果需要从
doInBackground
更新GUI,请记住使用
invokeLater

在我的情况下,我有这样的事情:

  • doInBackground
    执行“打开文件”例程,定期创建Swing组件并将其添加到GUI中
  • 取消时(通过带有取消按钮的进度条对话框),
    done
    将删除
    doInBackground
    期间创建的所有组件

有时,这些操作会重叠,
doInBackground
会在执行擦除后继续创建组件。对用户来说,按Cancel键似乎偶尔不起作用,只是调试显示正在调用
done
。没有其他解释,除了SwingWorker的这种行为

这可能是一个与stdoutIf的竞争条件的演示,如果程序员是对的,包括sysout调用上的时间戳应该显示它。。。跟踪这一点的一个策略是在IDE中为Swingworker插入源代码,并在done和doInBackgroun的最后一步上设置断点。。。只是一个想法…这不是仅仅因为在EDT上调用了done,并且doInBackground在它自己的线程上运行,所以它们不必一个接一个地出现吗?并自动取消已完成的呼叫。另外,只要在打印之前在catch块中添加另一个sleep,您每次都会看到它。支持
SwingWorker
Future
正在取消,并且在同一
线程的上下文中调用了
done
方法。这意味着
doInBackground
方法正在运行的
Thread
被调度运行并检测中断之前,可能会执行
done
。。。
@Override
protected Void doInBackground() {
    try {
        // ...
    } finally {
        // some cleanup inside 'doInBackground'
        if (isCancelled()) {
            // ...
        } else {
            // ...
        }
    }
    return (Void) null;
}
@Override
protected void done() {
    try {
        get();
    } catch (CancellationException x) {
        // ...
    } catch (InterruptedException x) {
        // ...
    } catch (ExecutionException x) {
        // ...
    }
}