【问题标题】:How should I terminate a looped sub-thread in Java?我应该如何终止 Java 中的循环子线程?
【发布时间】:2010-02-23 19:51:51
【问题描述】:

当我要终止一个循环线程时,我需要做一些清理工作。比如保存一个缓冲区,以便稍后继续。

PseudoCode: 
private class CalculatePI(Byte[] resume) implements Runnable{
    public void Run(){
       while(true){
          resume=resumeCalculating(resume);
       }
    }
}
Thread calculator= new Thread(new CalculatePI(Byte[] resume)); 
Thread.sleep(200); 
//And now I want to kill calculator

那么最好的实现方式是什么?

  1. 使用标志:但问题是如果 resumeCalculating() 需要(编辑:很长时间)forever 才能结束?
  2. 在计算器中加入异常,如何?
  3. 我可以使用事件监听器之类的吗?我以为它们是用于 GUI 的
  4. 停下来? Class Thread 包含某种解构器,当线程终止时会调用它,我可以在那里进行处理吗?

所有者编辑:

我知道我可以使用旗帜。但是考虑一下:

    public void Run(){
       while(true){
          resume=calculate_stepone(resume); //takes one minute
          resume=calculate_steptwo(resume); //takes two minutes
          resume=calculate_stepthree(resume); //takes three minutes
          resume=calculate_steplast(resume); //takes four minutes
       }
    }

在每行之间添加if(flag) saveResultsAndExit(); 是实用还是漂亮? 我只想把处理了一半的结果扔掉,保存之前的结果。

【问题讨论】:

    标签: java multithreading terminate


    【解决方案1】:

    停止线程的正确方法是interrupt

    如果线程中运行的任务正在执行 IO 或正在使用sleep,那么它将收到信号(此时为InterruptedException);否则任务应定期轮询以查看其是否为interrupted

    让我们修改原始海报的伪代码:

    private class CalculatePI(Byte[] resume) implements Runnable{
        public void Run(){
           while(!Thread.interrupted()) { //###
              resume=resumeCalculating(resume);
           }
        }
    }
    Thread calculator= new Thread(new CalculatePI(Byte[] resume)); 
    calculator.run(); //###
    //...
    //And now I want to kill calculator
    calculator.interrupt(); //### sends the signal
    //...
    calculator.join(); //### actually waits for it to finish
    

    【讨论】:

    • 只是不要忘记interrupted() 也会清除中断状态,因此后续调用将返回false
    【解决方案2】:

    回答 1.:您也可以处理 resumeCalculating() 中的中止标志。

    【讨论】:

    • 是的,我可以在 resumeCalculating() 中处理中止标志,但这并不像我希望的那样漂亮。 resumeCalculating 应该只关心计算 PI,而不是处理它应该如何死亡。该代码最好在计算器线程中使用。如果我有很多步骤呢?
    【解决方案3】:

    最好使用一个标志,等待一段时间让线程结束,如果没有(resumeCalculating 没有返回)手动终止线程。最好不要在 resumeCalculating 中涉及太多基于线程的逻辑,这实际上取决于它是如何实现的,以及在操作中途中止的难易程度。

    【讨论】:

      【解决方案4】:

      设计您的程序,使 resumeCalculating 不会永远持续下去。此外,同步访问您的标志。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-20
        相关资源
        最近更新 更多