我目前正在从服务运行一个线程来做一些后台工作。 现在有可能线程崩溃或者我想 从服务中断线程。那么我应该如何:
- 停止线程 realiable, (hard)
- 捕获异常并调用有关崩溃的服务
- 如果在 sleep() 时被中断则处理 InterruptedException
- Thread.isInterrupted 是检测线程是否停止的好方法吗?
到目前为止我所做的是:
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
doMyBackgroundWork();
sleep();
}
}catch(Exception e){
ExceptionHandler.logAndSendException(e);
Thread.currentThread().interrupt();
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
LOG.i("Thread stops now.");
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
//what to do here? it can happen because I stopped it myself
}
}
所以一开始我一直在运行线程,直到它被中断。 如果发生任何异常,我想启动一个新线程,因此 我的服务实现了一个监听器接口(interface),我调用它,一旦 抛出异常。我知道不鼓励捕获一切, 但我需要知道线程是否停止,而不需要轮询 Thread.isAlive() 每时每刻。
除了我上面的四个问题:
- 我的代码可靠吗?它能满足我的需求吗?
- 可以在线程本身上调用中断吗?
谢谢!
最佳答案
您实际上并没有中断自己的线程,因为 catch
block 在 while 循环之外。因此,任何异常都会立即停止执行。
中断本质上只是一个请求(通常来自另一个线程)停止你正在做的事情。线程可以随意忽略它并继续做它正在做的事情。通常,您必须抛出异常以响应中断,或以其他方式停止执行,例如从循环中中断(您需要围绕 //what to do here?
注释)。碰巧一些库方法是“响应中断”的,这意味着如果线程被中断,它们将抛出异常,例如 Thread.sleep()
,您很可能在 sleep
调用。
我建议选择 Java Concurrency In Practice。在优秀的并发资料中,有一个关于中断的章节很有帮助。
编辑: 我会删除您中断自己线程的代码。您还需要将 InterruptedException 作为运行时异常重新抛出,以退出执行循环。通常人们会创建一个新的异常来扩展 RuntimeException,类似于 MyInterruptedException。然后,您可以将它添加到循环周围的 catch block 中,以便您知道线程何时被中断与执行失败。
作为一般示例,您可以执行以下操作:
public void run() {
try {
while (true) {
// check for interrupts in the loop, or somewhere in the work method
if (Thread.interrupted()) {
throw new MyInterruptedException("Important thread interrupted.");
}
doMyBackgroundWork();
sleep();
}
}
catch(Exception e){
ExceptionHandler.logAndSendException(e);
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
catch(MyInterruptedException i) {
LOG.i("Execution stopping because of interrupt.");
}
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
throw new MyInterrptedException(e);
}
}
关于java - 崩溃后停止线程/线程调用自身中断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32278607/