Android - 停止线程的最佳和安全的方法

And*_*oid 76 android thread-safety

我想知道在Android中阻止线程的最佳方法是哪种.我知道我可以使用AsyncTask而不是它,并且有一种cancel()方法.我必须Thread在我的情况下使用s.这是我正在使用的方式Thread:

Runnable runnable = new Runnable() {
        @Override
        public void run() {
            //doing some work
        }
    };
new Thread(runnable).start();
Run Code Online (Sandbox Code Playgroud)

那么,有没有人知道哪个是阻止线程的最佳方法?

Chr*_*ris 81

你应该让你的线程支持中断.基本上,您可以调用yourThread.interrupt()停止线程,并且在run()方法中,您需要定期检查其状态Thread.interrupted()

这是一个很好的教程在这里.


Mal*_*olm 28

这种情况与标准Java没有任何不同.您可以使用标准方法来停止线程:

class WorkerThread extends Thread {
    volatile boolean running = true;

    public void run() {
        // Do work...
        if (!running) return;
        //Continue doing the work
    }
}
Run Code Online (Sandbox Code Playgroud)

主要思想是不时检查该字段的值.当您需要停止线程时,您将设置running为false.此外,正如克里斯指出的那样,您可以使用中断机制.

顺便说一句,当您使用AsyncTask时,您的apporach将没有太大差异.唯一的区别是您必须isCancel()从您的任务调用方法而不是具有特殊字段.如果你调用cancel(true),但没有实现这个机制,线程仍然不会自行停止,它将运行到最后.


Kon*_*che 18

在Android上,适用的规则与普通Java环境相同.在Java中,线程不会被杀死,但是线程的停止是以合作的方式完成的.要求线程终止,然后线程可以正常关闭.

通常使用一个volatile boolean字段,当该字符被设置为相应的值时,该字段定期检查并终止.

不会用a boolean来检查线程是否应该终止.如果您使用volatile的场调节剂,这将工作可靠,但如果你的代码变得更加复杂,对于而是使用内的其他阻止方法while循环,它可能发生,你的代码将不会终止所有或至少需要更长的时间,你可能想要.

某些阻塞库方法支持中断.

每个线程都有一个布尔标志中断状态,你应该使用它.它可以像这样实现:

public void run() {

   try {
      while(!Thread.currentThread().isInterrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }

}

public void cancel() { interrupt(); }
Run Code Online (Sandbox Code Playgroud)

源代码取自Java Concurrency in Practice.由于该cancel()方法是公共的,您可以让另一个线程根据需要调用此方法.

还有一个命名很差的静态方法interrupted,它清除当前线程的中断状态.

  • 在Android Studio中说,从未在相应的try块中抛出异常'java.lang.InterruptedException'吗? (2认同)
  • @CraPo 在 while 循环之前添加: `if (Thread.interrupted()) { throw new InterruptedException();}` (2认同)

Mat*_*att 16

Thread.stop()可能被用来停止一个线程方法已经过时; 了解更多信息; 为什么Thread.stop,Thread.suspend和Thread.resume已弃用?.

你最好的选择是拥有一个线程本身参考的变量,并在变量等于某个值时自愿退出.然后,当您希望线程退出时,可以操作代码中的变量.当然,您也可以使用AsyncTask.

  • AsyncTask实际上不是中断机制的替代品,它更像是与UI交互的工具.正如我在答案中指出的那样,如果您希望能够在执行期间停止它,您仍然必须在AsyncTask中实现与任何常见线程中相同的机制. (4认同)