Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.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 如何停止线程?_Java_Android_Multithreading - Fatal编程技术网

Java 如何停止线程?

Java 如何停止线程?,java,android,multithreading,Java,Android,Multithreading,我正在应用程序的onCreate方法中启动一个新线程,如下所示: stepsLogger = new Runnable() { while(!Thread.currentThread().isInterrupted()){ //my code try { Thread.currentThread().sleep(10000); } catch (InterruptedException e) { e.printStackTrace(

我正在应用程序的onCreate方法中启动一个新线程,如下所示:

stepsLogger = new Runnable() { 

while(!Thread.currentThread().isInterrupted()){

    //my code

    try {
        Thread.currentThread().sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
  }
};

loggerThread = new Thread(stepsLogger);
loggerThread.start();
虽然它没有被打断,但它应该每10秒做一次

我在Runnable开始时记录了一些文本,以查看代码运行的频率。我第一次运行应用程序时,它很好,但每次重新启动时,文本记录得更频繁,这意味着运行的线程更多

我已尝试在onDestroy方法中阻止它们:

@Override
protected void onDestroy() {
    super.onDestroy();
    loggerThread.interrupt();
    loggerThread = null;
}

如何确保在应用程序重新启动时停止旧线程?

您可以使用可变布尔变量来确定何时停止。大概是这样的:

class WorkerRunnable implements Runnable {

    private volatile boolean shouldKeepRunning = true;
    public void terminate() {
        shouldKeepRunning = false;
    }

    @Override
    public void run() {
        while (shouldKeepRunning) {
            // Do your stuff
        }
    }
}
要启动它:

WorkerRunnable runnable = new WorkerRunnable();
new Thread(runnable).start();
要阻止它:

runnable.terminate();
interrupt将用InterruptedException唤醒休眠线程,因此您已经完成了大部分工作。我将按以下方式更改您的循环:

while (true) {
  // some code
  try {
    Thread.currentThread().sleep(10000);
  } catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // restore the thread's interrupted flag
    break;
  }
}
重新中断线程的部分是微妙的。在这篇文章中,您可以从一位主要的JVM架构师那里了解更多关于它的信息:


如果这个链接失效,其要点是线程中断可以有多个接收者。捕获异常会隐式清除线程的中断标志,因此重新设置它很有用。

loggerThread.stop;打断别人是正确的想法,但从表面上看,这种打断永远不会被称为。@bowmore我认为你是对的。我在onDestroy中添加了一个日志。当我点击debug应用程序时,它只打印启动应用程序,其他什么都没有。我不是安卓专家,但我认为你需要在其他地方进行中断。不能保证onDestroy会在活动中被调用。OP中的循环很好,因为Runnable位于堆栈的根,在这种情况下,实际上不需要重新打断。谢谢,这很有效!不过,仍然需要在onDestroy中中断它。似乎当一个中断没有被调用时,另一个会被调用。另外,将loggerThread设置为null似乎是不必要的,因为它在没有它的情况下工作。@bowmore您当然是对的-这是不必要的;只是良好的线程卫生。当这个循环被复制到executor服务任务时,它将非常有用:您完全正确,看到有人实际正确地处理InterruptedException,这是令人耳目一新的。