崩溃后停止线程/线程调用中断?

时间:2015-08-28 19:34:54

标签: java android multithreading

我目前正在从服务运行一个线程来做一些后台工作。 现在有可能线程崩溃或我想 从服务中断线程。那我该怎么做:

  1. 停止线程可信,(硬)
  2. 捕获异常并致电服务部门了解崩溃
  3. 如果sleep()
  4. 中断,则处理InterruptedException
  5. 是Thread.isInterrupted检测线程是否停止的好方法吗?
  6. 到目前为止,我所做的工作如下:

    @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() 每时每刻。

    除了我上面的四个问题:

    • 我的代码是否可靠并且能满足我的需求?
    • 可以在线程本身上调用中断吗?

    谢谢!

2 个答案:

答案 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()方法,它确实暂停目标线程。

不仅仅是一个解决方案,但如果在任何崩溃之后保持线程运行并运行紧急(或自身)非常关键,您可以将其作为单独的应用程序/进程运行,并获取进度状态(如果有的话) )确保您的目标线程/应用程序不会冻结(阻止,...)