2015-01-15 104 views
0

我正在努力处理提交给invokeall()的任务之一抛出CancellationException强制程序不终止的用例。在CancellationException的情况下,如何确保此程序能正常终止?ExecutorService invokeall线程池问题

我怎么找到我的程序没有终止干净?如果程序没有终止,我正在使用netbeans并在右下角显示进度条。

这里是代码:

 int poolSize = Runtime.getRuntime().availableProcessors(); 
     ExecutorService pool = Executors.newFixedThreadPool(poolSize); 
     Set<Callable<Object>> tasksSet = new HashSet<>(); 
     tasksSet.add(new Task1()); 
     tasksSet.add(new Task2()); 
     tasksSet.add(new Task3()); 

     List<Future<TrendLineStatisticsVO>> resultSet = pool.invokeAll(tasksSet, 1, TimeUnit.MINUTES); 
     for (Future<Object> future : resultSet) { 
      Object result; 
      try { 
        result = future.get(5, TimeUnit.SECONDS); 
      } catch (InterruptedException ex) { 
       ex.printStackTrace(); 
       Logger.getLogger(CallableDemo.class.getName()).log(Level.SEVERE, null, ex); 
      } catch (ExecutionException ex) { 
       ex.printStackTrace(); 
       Logger.getLogger(CallableDemo.class.getName()).log(Level.SEVERE, null, ex); 
      } catch (TimeoutException ex) { 
       ex.printStackTrace(); 
       Logger.getLogger(CallableDemo.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
     pool.shutdown(); 

而且Task1代码:

public class Task1 implements Callable<Object> { 

    @Override 
    public Object call() throws Exception { 
     //This for sure takes days to complete, so should through Cancellation exception because timeout on invokeall set to 1 minute 
     long val = 0; 
     for (long i = 0; i < Long.MAX_VALUE - 5000; i++) { 
      val += i; 
     } 
     return "Sucessfull Task1 object..."; 
    } 

} 

Task2Task3代码也只是这两个类同样在回路检查使用Integer.MAX_VALUE的。

回答

1

这里有两个问题:

1)

Javadoc:未完成将被取消

任务。

因此,您将不得不编码您的Task以响应中断。在后台发生的事情与future.cancel(true)类似,如果任务在指定的时间内未完成,则参数中的true表示执行任务的线程为interrupt()。就像我刚才提到的,你的任务将不得不寻找中断。类似的东西来:

@Override 
public Object call() throws Exception { 
    //This for sure takes days to complete, so should through Cancellation exception because timeout on invokeall set to 1 minute 
    long val = 0; 
    for (long i = 0; i < Long.MAX_VALUE - 5000; i++) { 
     if(Thread.interruped()){ 
      throw new RuntimeException("Did not complete in time: " + i); 
     } 
     val += i; 
    } 
    return "Sucessfull Task1 object..."; 
} 

如何我发现我的程序没有结束干净吗?如果程序没有终止,我正在使用netbeans并在右下角显示进度条。

没有我上面的更新程序将永远不会结束,因为线程池仍在运行。 shutdown将不执行任何操作,因为任务尚未完成(带有取消的事件)。

2)

已被取消,通过定义一个任务,没有完成(甚至开始),所以在未来的调用get很快就会失败。你可以问未来是否取消​​。

+1

现在我看到了错误,感谢您的时间和解释! – kosa 2015-01-15 17:56:42

+0

如果你不介意的话,我会有小的跟进,在这种情况下,而不是为了循环,让我们说我们正在调用10种不同的方法,它做了一些操作,问题是我们不知道当我们控制的时候,我们超时,那我们该如何处理中断?有什么建议么? – kosa 2015-01-15 18:12:31

+1

不幸的是,没有简单的方法来处理这个用例。例如,如果其他方法之一正在从'InputStream'中读取,其中'read()'方法不响应中断。你可能会运气不好(除非你可以,关闭InputStream)。 – 2015-01-15 18:31:05