如何停止长时间运行的功能

时间:2016-03-01 10:32:55

标签: java multithreading

考虑以下代码:

class Solver {

   private boolean abort = false;

   public void solve(List<Case> cases) {
       while(!abort) {
           for(Case c : cases)
               compute(c); // method that take too long to finish
       }
   }

  // a bunch of methods

   public void abort() {
       abort = true;
   }
}

// in another class
Solver solver = new Solver();
solver.solve(cases);

public void onSolveAborted() {
    solver.abort();
}

如何更改此解决方案,以便我可以立即中止解决功能。我知道我可以在Solver类中实现Runnable接口,所以我可以停止该线程。这将在我们的代码中引入许多更改,我不知道我们使用的框架是否允许创建线程。

3 个答案:

答案 0 :(得分:1)

如果不使用线程,这是不可能的。在运行的线程停止之前,必须设置 for tag in tags: print tag, tags[tag] 。看一下这个例子:

abort()

很简单,它在一个线程中启动求解。主线程最多等待30秒,然后中断class Solver implements Runnable { private List<Case> cases; public Solver(List<Case> cases) { this.cases = cases; } private void compute(Case c) { try { // Do some computation here } finally { // Sound the horns! Abandon ship! } } public void solve(List<Object> cases) { for (Case c : cases) { try { compute(c); // method that take too long to finish } catch (InterruptedException e) { // Hmm, maybe I should take the hint... break; } } } public void run() { solve(cases); } public static void main(String args[]) { List<Case> cases = new ArrayList<Case>(); // Populate cases Thread t = new Thread(new Solver(cases)); t.run(); do { // Wait 30 seconds t.join(30 * 1000); // Not done yet? Lets drop a hint.. if(t.isAlive()) { t.interrupt(); } } while (t.isAlive()); } } 方法。 solve方法捕获中断并优雅地退出计算。与使用solve的解决方案不同,这会从你的代码中的任何地方启动boolean abort(你应该相应地处理异常!),允许你随时停止执行。

如果您想要更多控制权,可以在InterruptedException内添加try.. catch,这样您就可以使用compute子句关闭所有已打开的文件或其他内容。或许更好的是,在计算机中有一个finally来处理关闭&#34; nice&#34;方式和try.. finally方法中的try.. catch (InterruptedException)来处理中断情况下发生的事情(简而言之,清理逻辑和中断逻辑不必采用相同的方法)。

答案 1 :(得分:0)

做这样的事情

比方说,你有100个案例,10个已经解决,你想要中止剩余90个。 在您的代码中,您将在一次迭代中解决所有情况,之后循环检查中止。

public void solve(List<Case> cases) {
    Iterator<Case> iterator = cases.iterator();
    while (iterator.hasNext() && !abort) {
        Case c=iterator.iterator.next();
        compute(c);
    }
 }

答案 2 :(得分:0)

将您的班级更改为Runnable并使用ExecutorService运行它。然后你可以使用方法&#34; shutDown()&#34;或&#34; shutDownNow()&#34;方法。这比你在自己的问题中建议的更干净,更少侵入。手动杀死线程是一个非常糟糕的想法。在JDK本身的某些方面,在线程方法&#34; kill()&#34;被杀了,因为没有干净的方法可以做到这一点