停止/销毁线程

foo*_*man 19 service multithreading android

我有一个启动Thread和Runnable的服务.

t = new Thread(new Runnable() {
    public void run() {
        doSomething();
    }
});

t.start();
Run Code Online (Sandbox Code Playgroud)

该线程的原因是执行异步任务doSomething().现在让我们不要担心其他类AsyncTask.我已经尝试过它并不适用于我的情况.编辑:我不能使用AsyncTask,因为它仅适用于UI线程.这段代码必须在服务内部运行,所以nope,没有AsyncTask :(

doSomething()包含一些外部库,所以我遇到的问题是它可能挂在其中一个命令上,而不返回任何值(因此甚至不能进行错误检查)

为解决这个问题,我希望在某些时候破坏服务.

stopService(new Intent("net.MyService.intent));
Run Code Online (Sandbox Code Playgroud)

这很好,很容易在手机上验证.但是,即使生成它的服务被销毁,上面创建的Thread也将继续运行.

因此,我正在寻找在Service的onDestroy()中插入的正确命令,它将为我清理Thread.

t.destroy();
t.stop();
Run Code Online (Sandbox Code Playgroud)

都折旧并导致应用程序崩溃.

我从某个地方拿了这个代码

@Override
public void onDestroy() {

    Thread th = t;
    t = null;

    th.interrupt();

    super.onDestroy();
}
Run Code Online (Sandbox Code Playgroud)

但它仍然无效,线程继续运行.有帮助吗?

Jos*_*arl 11

线程destroystop方法本身就容易出现死锁,并且不安全.它们的存在也给人一种错觉,即当其他东西告诉它时,可能会有某种方法立即停止另一个线程.

我理解你的想法,从你的观点来看,他们是一个主线程,当这个线程没有收到来自它的工作线程的响应时,你想杀死它并重新启动它,而不关心它是什么.但是这些方法被弃用的原因是你应该关心线程的用途.很多.

如果线程锁定了您稍后需要使用的变量,该怎么办?如果一个线程打开了文件句柄怎么办?在所有这些情况下,还有更多情况下,简单地停止当前操作的线程会让事情变得一团糟 - 很可能你的应用程序只会在线路上崩溃.

因此,为了使线程可以中断或取消或可停止,它必须自己管理.如果某个线程或操作无法自行中断,那么就不能打断它 - 假设这样做会不安全.

如果你是runnable字面意思

public void run() {
   doSomething();
}
Run Code Online (Sandbox Code Playgroud)

然后没有办法打断它.人们希望,如果doSomething是一个长期的操作,可能有一种方法可以通过类似的方式逐步与之交互

public void run() {
   while (running) {
       MyParser.parseNext();
   }
}
Run Code Online (Sandbox Code Playgroud)

或者能够通过引用传入一个变量来指示线程是否被中断,并且希望该方法在适当的位置中断自己.

记住blocking操作是阻塞的.没有办法解决这个问题,你无法在中途取消它.


FrV*_*aBe 1

您是否检查了Thread API JavaDoc中引用的Java Thread Primitive Deprecation Documentation 。您会发现一些提示来解决您的问题。

  • 该链接基本上重申了我面临的所有问题和限制。该链接讨论了如何使用interrupt() 代替stop(),这正是我正在做的事情。Interrupt() 的问题是它只适用于 sleep()、wait() 和 join()。在我的代码中,挂起的线路不是这些,而且它永远不会恢复,即使在一小时后也是如此。线程卡在该行,没有中断可以将其解救。 (3认同)