我目前正在从服务运行一个线程来做一些后台工作。 现在有可能线程崩溃或我想 从服务中断线程。那我该怎么做:
到目前为止,我所做的工作如下:
@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
}
}
所以一开始我运行我的线程直到它被中断。 如果发生任何异常,我想启动一个新的Thread 我的服务实现了一个监听器接口,我称之为 抛出异常。我知道劝阻一切都是气馁的 但我需要知道线程是否停止,而不轮询Thread.isAlive() 每时每刻。
除了我上面的四个问题:
谢谢!
答案 0 :(得分:1)
您实际上并没有中断自己的线程,因为catch
块在while循环之外。因此,任何异常都会立即停止执行。
中断本质上只是一个请求(通常来自另一个线程)停止做你正在做的事情。线程可以自由地忽略它并继续做它正在做的事情。通常你必须抛出异常以响应中断,或者以某种其他方式停止执行,例如只是从循环中断(你需要围绕//what to do here?
注释)。碰巧有些图书馆方法会对中断做出反应。这意味着如果线程被中断,它们将抛出异常,例如Thread.sleep()
,您最有可能在sleep
电话中使用。
我建议选择Java Concurrency In Practice。在优秀的并发材料中,有一章关于中断非常有用。
修改的: 我会删除你打断自己的线程的代码。您还需要重新抛出InterruptedException作为运行时异常以退出执行循环。通常人们会创建一个新的Exception来扩展RuntimeException,类似于MyInterruptedException。然后,您可以将它添加到循环周围的catch块中,以便您知道线程何时中断与执行失败。
作为一般示例,您可以执行以下操作:
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);
}
}
答案 1 :(得分:0)
我们有一个名为stop()
(Thread.stop(void):void
)的优秀且有效的方法,该方法已被弃用,但它有效且很可爱。
请注意,stop()
会将ThreadDeath
引发到目标线程,这不是一个例外(它也可以是任何其他throwable
),而是一个Error
,所以你的代码不会发现有关此事的任何信号。
public void run() {
try {
while (<<using_a_volatile_bool_type_is_better>>) {
...
}
}catch(Throwable t){/**/}/*use throwable instead of exception.*/}
}
除了亲爱的朋友stop()
,我们也有pause()
方法,它确实暂停目标线程。
不仅仅是一个解决方案,但如果在任何崩溃之后保持线程运行并运行紧急(或自身)非常关键,您可以将其作为单独的应用程序/进程运行,并获取进度状态(如果有的话) )确保您的目标线程/应用程序不会冻结(阻止,...)