Java SwingWorker IsInterputed在取消后返回false

Java SwingWorker IsInterputed在取消后返回false,java,multithreading,swingworker,Java,Multithreading,Swingworker,我有一段代码可以下载一个文件。这发生在SwingWorker doInBackground方法中。(参见下面的代码)文件是一个文件对象(temp dir)。连接是一个URLConnection对象,它保存要下载的文件的url。(url.openConnection()) 下载在SwingWorker中正常工作,除了取消 SwingWorker<Integer,Integer> swingWorker = new SwingWorker<Integer,Integer>()

我有一段代码可以下载一个文件。这发生在SwingWorker doInBackground方法中。(参见下面的代码)文件是一个文件对象(temp dir)。连接是一个URLConnection对象,它保存要下载的文件的url。(url.openConnection()) 下载在SwingWorker中正常工作,除了取消

SwingWorker<Integer,Integer> swingWorker = new SwingWorker<Integer,Integer>() {

    int contentLength = 0;
    int bytesDownloaded = 0;

    double speed = 0;

    @Override
    protected Integer doInBackground() throws Exception {

    setStatus("Dowloading...");

    URL url = null;
    URLConnection connection = null;

    try {
        url = new URL(MainScreen.getUrl()); // Gets a URL entered earlier to dowload
        connection = url.openConnection();
    } catch (Exception ex) {
        ex.printStackTrace(System.err);
    }

    BufferedOutputStream outputStream = null;
    try {
        BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
        outputStream = new BufferedOutputStream(new FileOutputStream(doelBestand));

        contentLength = connection.getContentLength();

        long start = System.nanoTime();
        final double nanosPerSecond = 1000000000.0;
        final double bytesPerMB = 1024 * 1024;

        while(true) {
        int b = inputStream.read();
        bytesDownloaded += b;
        speed = nanosPerSecond / bytesPerMB * bytesDownloaded / (System.nanoTime() - start + 1);
        process();
        if (b == -1 || Thread.interrupted()) {
            break;
        }
        outputStream.write(b);
        }
    } catch (IOException ex) {
        ex.printStackTrace(System.err);
    } finally {
        try {
        if(outputStream != null) {
            outputStream.close();
        }
        } catch (IOException ex) { }
        try {
        if(connection != null) {
            connection.getInputStream().close();
        }
        } catch (IOException ex) {  }
    }
    return 100;
    }

    @Override
    protected void done() {
    progressBar.setIndeterminate(false);
    progressBar.setValue(100);
    lblPercent.setText("100 %");
    btnStartCancel.setEnabled(false);
    btnOpenFolder.setEnabled(true);
    chkCloseOnFinish.setEnabled(false);
    state = State.DONE;
    }

    protected void process() {
    DecimalFormat df = new DecimalFormat("0.##"); 
    if(speed > 0) {
        lblDownloadSpeed.setText(df.format(speed) + " mb/s");
    }

    if(contentLength > 0) {
        Integer percent = (int) (bytesDownloaded / (contentLength / 100.0));
        progressBar.setValue(percent);
        lblPercent.setText(percent + " %");
    } else {
        progressBar.setIndeterminate(true);
    }

    }
};
但是
isInterrupted()
总是返回false,因此它继续运行线程,但是cancel函数确实返回true

我在(!isCancelled())时也尝试了
,但也不断返回false

还有一个问题是,当它被取消时,它永远不会停止,因此它成为一个无限线程。(int b在添加时继续运行,bytesDownloaded将不断增长)。它不是无限的,只要下载完成而没有取消(那么b将是-1),循环就会中断


如何确保swingWorker将中止下载?

我猜阻塞方法是来自InputStream类的read(),或者其他方法正在阻塞一个。因此,Despides,您需要编写一个结构良好的方法,但其中一个操作会阻塞执行流程。因此,除了插入线程(这是终止线程所必需的)之外,您还必须中断阻塞操作(我猜是读取输入流),首先,确保您调用的
SwingWorker
实例与启动后台任务时使用的实例相同。由于您没有在显示给我们的
SwingWorker
语句中创建您的
SwingWorker
,因此很可能您在错误的位置创建了它(并覆盖了引用变量)。此外,当您从后台线程访问甚至操作GUI时,您的实现从根本上被破坏了。感谢您的回复@霍尔格switch语句紧跟在swingworker之后。两者的功能也相同。如您所见,它在就绪状态下成功执行
swingWorker.execute()
没有其他线程,这意味着我们可以排除它可能被覆盖的可能性。从worker更新GUI的更合适的方法是什么?您在
开关
语句之前创建swingworker,也就是说,即使
状态
正在下载
,您也在创建swingworker?想想看。正确的更新方式是。您可以使用
属性更改侦听器
通知或
发布
/
进程
队列。为什么不尝试使用自定义标志?说布尔值(而不是使用SwingWorker的信号基础系统)。我怀疑cancel方法只设置了一个内部布尔值,这与isCanceled()上返回的值相同。
switch(state) {
    case READY:
    state = State.DOWNLOADING;
    btnStartCancel.setText("Cancel");

    swingWorker.execute();
    break;
    case DOWNLOADING:
    swingWorker.cancel(true);
        progressBar.setIndeterminate(false);
    lblPercent.setText("Download was cancelled by the user.");
    btnStartCancel.setText("Start");
    btnStartCancel.setEnabled(true);
    break;
    case DONE:
    // Do nothing
    break;

}