如何正确停止线程?

10 浏览
0 Comments

如何正确停止线程?

我有一个表示下载任务单元的类。当调用cancel()方法时,我需要停止下载、清除已下载的数据并关闭连接。我知道在Java中有很多关于停止机制的讨论。我不能使用这个答案:这个答案,因为循环中没有操作。那么我应该如何正确地做到这一点呢?

0
0 Comments

如何正确停止线程?

在上述内容中,问题的出现原因是需要在可能运行时间长的读取过程中进行中断。解决方法是在循环中使用条件判断来控制线程的执行。

具体实现代码如下:

while ((count = input.read(data)) != -1 && isRunning) {
    // 执行读取操作
}

然而,有人认为这不是一个好主意。可以在离开循环时取消任务。例如,在`out.close()`方法中可以这样做。你可以在while循环之后执行这个操作,就像你正在做的那样。这个答案实现了你所要求的功能。

然后,有人提出了一个问题,他认为在每一行代码之后都要检查布尔表达式(最好是在每一行之后),但这样做是否是一个好的做法?

另一个人给出了一个解答,他认为应该确定哪些操作是阻塞的或者耗时的。当退出while循环时,昂贵的部分应该已经完成了,所以为什么要在那个时候进行“中断”呢?

为了正确停止线程,可以在循环中使用条件判断来控制线程的执行,并在循环外部进行耗时操作。这样可以保证线程能够在合适的时机停止,并且避免不必要的中断。

0
0 Comments

在这个问题中,原因是无法正确停止线程,除非让线程运行的代码是可中断的,也就是说,它会检查自己是否被中断。在这种情况下,可以通过调用`Thread.interrupted()`来检查线程是否被中断,并在需要的地方执行相应的操作。

解决方法是在代码中添加中断检查的逻辑。例如,在上述代码中,可以在循环中添加`!Thread.interrupted()`的条件来检查线程是否被中断。当线程被中断时,可以执行相应的操作,例如取消下载或执行清理操作。

具体的代码示例如下:

final Thread cancelable = new Thread() {
    public void run() {
        int count;
        try {
            ...
            while ((count = input.read(data)) != -1 && !Thread.interrupted()) {
                total += count;
                // 发布进度信息....
                // 这之后会调用 onProgressUpdate
                mListener.onDownloadProgress(mDownloadLink, (int) ((total * 100) / contentLength));
                // 写入数据到文件
                output.write(data, 0, count);
            }
            if (Thread.interrupted()) {
                mListener.onDownloadCanceled(mDownloadLink);
            }
            ...
        }
    }
});

为了停止下载,只需调用`cancelable.interrupt()`即可。

总之,要正确停止线程,需要在代码中添加中断检查的逻辑,并在需要的地方执行相应的操作。在这个例子中,通过在循环中添加`!Thread.interrupted()`的条件来检查线程是否被中断,并在需要的地方执行取消下载操作。

0
0 Comments

如何正确停止线程?

在上述代码中,存在一个问题,即如何正确停止线程。具体而言,当cancel标志被设置为true时,线程应该立即停止运行。

解决方法是通过设置一个标志变量cancel,当该变量为true时,线程会抛出一个自定义的DownloadCancelException异常。在异常处理代码块中,可以执行一些清理操作,如清除已下载的内容。

以下是修改后的代码:

public class Task implements Runnable {
   private boolean cancel;
   
   public void run() {
     try {
       while (yourCondition) {
          // 执行工作任务
          if (cancel) {
             throw new DownloadCancelException();
          }
       }
     } catch (DownloadCancelException e) {
        // 在这里清理已下载的内容
     }
   } 
   
   public void kill() {
         cancel = true;
   }
}

在上述代码中,run方法中的主循环会不断执行工作任务,直到cancel标志被设置为true。当cancel标志为true时,会抛出DownloadCancelException异常。在异常处理代码块中,可以执行清理下载内容的操作。

外部可以通过调用kill方法来设置cancel标志为true,从而停止线程的运行。

通过以上的修改,我们可以正确地停止线程。

0