如何正确停止线程?
如何正确停止线程?
我有一个表示下载任务单元的类。当调用cancel()方法时,我需要停止下载、清除已下载的数据并关闭连接。我知道在Java中有很多关于停止机制的讨论。我不能使用这个答案:这个答案,因为循环中没有操作。那么我应该如何正确地做到这一点呢?
如何正确停止线程?
在上述内容中,问题的出现原因是需要在可能运行时间长的读取过程中进行中断。解决方法是在循环中使用条件判断来控制线程的执行。
具体实现代码如下:
while ((count = input.read(data)) != -1 && isRunning) { // 执行读取操作 }
然而,有人认为这不是一个好主意。可以在离开循环时取消任务。例如,在`out.close()`方法中可以这样做。你可以在while循环之后执行这个操作,就像你正在做的那样。这个答案实现了你所要求的功能。
然后,有人提出了一个问题,他认为在每一行代码之后都要检查布尔表达式(最好是在每一行之后),但这样做是否是一个好的做法?
另一个人给出了一个解答,他认为应该确定哪些操作是阻塞的或者耗时的。当退出while循环时,昂贵的部分应该已经完成了,所以为什么要在那个时候进行“中断”呢?
为了正确停止线程,可以在循环中使用条件判断来控制线程的执行,并在循环外部进行耗时操作。这样可以保证线程能够在合适的时机停止,并且避免不必要的中断。
在这个问题中,原因是无法正确停止线程,除非让线程运行的代码是可中断的,也就是说,它会检查自己是否被中断。在这种情况下,可以通过调用`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()`的条件来检查线程是否被中断,并在需要的地方执行取消下载操作。
如何正确停止线程?
在上述代码中,存在一个问题,即如何正确停止线程。具体而言,当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,从而停止线程的运行。
通过以上的修改,我们可以正确地停止线程。