如何中断长时间运行的进程 - Java

时间:2018-02-13 10:31:58

标签: java multithreading interrupt

我有一个带有'进程'按钮的GUI。按下按钮时,将执行以下代码:

//Check for results truncation
boolean truncate = !jCheckBoxTruncate.isSelected();
String[] args = {fileName};
//run solution and draw graph
SpeciesSelection specSel = new SpeciesSelection(args, truncate);
Thread t = new Thread(specSel);
t.start();
long startTime = System.nanoTime();
cancelled = false;
jButtonCancel.setVisible(true);

new Thread() {
  @Override
  public void run() {
    while (!specSel.isFinished() && !cancelled) {
       double seconds = (System.nanoTime() - startTime) / 1000000000.0;
       jLabelProcessTime.setText("Processing Time: " + toTimeString(seconds));
       try {
          Thread.sleep(91);
       } catch (InterruptedException ex) {
          Logger.getLogger(SpecSelGUI.class.getName()).log(Level.SEVERE, null, ex);
       }
   }

jButtonCancel.setVisible(false);
jButtonProcess.setEnabled(true);
// If processing finished then display result graph, else the process was cancelled so stop the processing thread.
if (specSel.isFinished()) {
   ArrayList<Double> result = specSel.getResult();
   drawGraph(result);
}
else {
       t.interrupt();
     }
   }
}.start();

所以我有一个'Thread t'执行一个长时间运行的进程,一个匿名线程只是更新GUI上的处理时间并监视取消Thread t的请求。 SpeciesSelection类重写run(),如下所示:

@Override
public void run() {
   long start = System.nanoTime();
   try {
       result = specSel(args, truncate);//VERY LONG RUNNING PROCESS CALLED ONCE
   } catch (FileNotFoundException ex) {
       Logger.getLogger(SpeciesSelection.class.getName()).log(Level.SEVERE, null, ex);
   }
   finished = true;
       System.out.println("Process took " + ((System.nanoTime() - start) / 1000000.0) + "ms");
   }

我有一个取消按钮,将标志'cancel'设置为true。如果按下此按钮,我尝试中断线程t。但是,没有任何反应,线程继续运行。我想我错过了一些东西,并希望得到一些关于如何正确中断长时间运行进程/ Thread t的帮助。

1 个答案:

答案 0 :(得分:0)

我猜specSel(args, truncate);//VERY LONG RUNNING PROCESS CALLED ONCE并不支持中断。

为使中断机制正常工作,被中断的线程必须支持自己的中断。

线程如何支持自己的中断?

  1. 如果线程经常调用抛出InterruptedException的方法(如Thread.sleep()),则可以处理ExceptionHandler中的中断,如

    try {
       Thread.sleep(4000);
    } catch (InterruptedException e) {
    // We've been interrupted: no more messages.
       return;
    }
    
  2. 如果一个线程长时间没有调用抛出InterruptedException的方法怎么办?然后它必须定期调用Thread.interrupted,如果收到中断,则返回true。例如:

    for (int i = 0; i < inputs.length; i++) {
        if (Thread.interrupted()) {
            // We've been interrupted: no more crunching.
            return;
        }
    }
    
  3. 由于后者属于你,我建议你在里面做第二个建议 specSel(args, truncate);支持其中断。当然,您可以执行return以外的其他操作。但这就是你想要的。