ScheduledExecutorService和ThreadPoolTask​​Executor在超时后中断任务

时间:2015-06-04 16:46:22

标签: java multithreading concurrency threadpool executorservice

我使用ExecutorService在超时后中断任务。我为此使用ScheduledExecutorService。首先我提交了线程并立即开始一次并保留创建的未来。之后我使用ScheduledExecutorService作为一项新任务,在一段时间后取消保留的未来。

//Start Spring executor to submit tasks
ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) ApplicationContextProvider.getApplicationContext().getBean("taskExecutor"); 

CompletionService completionService = new ExecutorCompletionService(taskExecutor);
//End Spring executor to submit tasks

// Start ScheduledExecutorService  to submit returned future object to timeout

ScheduledExecutorService executor = Executors.newScheduledThreadPool(Integer.parseInt(config.getProperty("DBPOLLER_COREPOOLSIZE")));

final Future<String> future = completionService.submit(batchJob); // Submit actual task and get future

// submit future

executor.schedule(new Runnable() {
      public void run() {
                         future.cancel(true);
      }
   }, dbPollerTimeOut, TimeUnit.MINUTES);

int count = taskExecutor.getActiveCount();

 if (count == 0) {

                taskExecutor.shutdown();
                executor.shutdown();
                finalExitStatus = 0;                    
                break;

            } 

我已经实现了以下url中的解决方案: ExecutorService that interrupts tasks after a timeout,它工作正常,直到超时,但一旦发生超时,它取消了我不接受的所有enter code here任务我的ThreadPool。我只需要取消长时间运行并达到超时的任务。

知道如何实现这个目标吗?

1 个答案:

答案 0 :(得分:0)

目前尚不清楚您的CompletionService是什么,并且您正在提交batchJob,因此很难确定问题的确切根本原因。但是,提交一些任务并在一段时间后取消它们的理想方案是将ScheduledExecutorService用于这两个目的。

因此,可以尝试在batchJob的实例上提交ScheduledExecutorService,即executor

final Future<String> future = executor.submit(batchJob); // Submit actual task and get future       

编辑更新 您应该在代码中进行的重大更改
我发现你永远不会阻止你的ScheduledExecutorService这是错误的,因为它占用的资源在你停止之前永远不会被释放。因此,您的更新代码应如下所示:

ScheduledExecutorService executor = Executors.newScheduledThreadPool(Integer.parseInt(config.getProperty("DBPOLLER_COREPOOLSIZE")));
final Future<String> future = executor.submit(batchJob); // Submit actual task and get future
executor.schedule(new Runnable() {
      public void run() {
        future.cancel(true);
        executor.shutdownNow();
      }
   }, dbPollerTimeOut, TimeUnit.MINUTES);