ScheduledExecutorService和ThreadPoolTask​​Executor在超时后中断任务 [英] ScheduledExecutorService and ThreadPoolTaskExecutor that interrupts tasks after a timeout

查看:398
本文介绍了ScheduledExecutorService和ThreadPoolTask​​Executor在超时后中断任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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;

            }  

我已经实现了以下网址中的解决方案: 在超时后中断任务的ExecutorService 正常运行,直到超时,但是一旦发生超时,它将取消ThreadPool中所有不可接受的enter code here任务.我只需要取消长时间运行并达到超时的任务即可.

有什么想法要实现吗?

解决方案

目前尚不清楚您的CompletionService是什么,并且您正在提交batchJob,因此很难说出您的确切原因问题.但是,提交少量任务并在一段时间后取消任务的理想方案是同时使用ScheduledExecutorService.

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

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);

I Used ExecutorService that interrupts tasks after a timeout.I use a ScheduledExecutorService for this. First I submitted the thread and it once to begin immediately and retain the future that is created. After that i use ScheduledExecutorService as a new task that would cancel the retained future after some period of time.

//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;

            } 

I have implemented the solution which is in below url: ExecutorService that interrupts tasks after a timeout, it was working fine, until timeout, but once timeout happens, it cancels all theenter code here tasks i ThreadPool which is not acceptable. I need to cancel only tasks that are long running and reach timeout.

Any idea how to achieve this?

解决方案

It is not clear what your CompletionService is, and you are submitting your batchJob on it, so it is hard to tell exact root cause of your problem. But ideal scenario of submitting few tasks and cancelling them after some time, is to use ScheduledExecutorService for both purposes.

So, can try submitting the batchJobon instance of ScheduledExecutorService i.e. executor.

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

EDIT UPDATE: Important change you SHOULD do in your code
I see that you are never stopping your ScheduledExecutorService which is wrong because resources it occupies will never be released until you stop it. So, your updated code should be as below:

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);

这篇关于ScheduledExecutorService和ThreadPoolTask​​Executor在超时后中断任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆