简体   繁体   English

Java线程池任务超时问题

[英]java thread pool task timeout issue

I have a thread pool: 我有一个线程池:

ThreadPoolExecutor pool = new ThreadPoolExecutor(cores, 50, 30L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3000));

And then I run: 然后我运行:

try {
    pool.execute(() -> 
{
  //Very very long task, fetching from an external URL
});
}catch(Exception e){
    e.printStackTrace();
}

I never get an exception, and this code waits for minutes. 我从来没有遇到异常,这段代码等待几分钟。 What should I do to make it cancel in 30 secs? 我应该怎么做才能使其在30秒内取消?

According to the documentation the 3th parameter, keepAlive, does not specify the await time for a specific task in the thread pool, but time till idle threads should be released from the pool. 根据文档,第三个参数keepAlive并未为线程池中的特定任务指定等待时间,而是直到从池中释放空闲线程为止的时间。

  * @param keepAliveTime when the number of threads is greater than * the core, this is the maximum time that excess idle threads * will wait for new tasks before terminating. 

For your desired behavior you should wrap your task in a FutureTask , then submit the future task to thread pool. 对于所需的行为,应将任务包装在FutureTask中 ,然后将将来的任务提交到线程池。 On the future task you can call get(timeout, timeunit) 在以后的任务中,您可以调用get(timeout,timeunit)

FutureTask<T> task = new FutureTask<T>(c);
pool.execute(task);
return task.get(timeout, timeUnit);

What you're specifying to be 30 seconds is the keepAliveTime of the idle threads of your executor. 您指定的30秒是执行程序的空闲线程的keepAliveTime This is the duration in which excess threads that are not currently processing tasks will be kept alive. 这是当前未处理任务的多余线程保持活动的持续时间。 Here excess threads is defined as threads created in addition to the one thread per core that your ThreadPoolExecutor will keep alive, depending on the corePoolSize that you've specified. 在这里,多余的线程被定义为除了您的ThreadPoolExecutor将保持活动的每个核心一个线程之外的线程,具体取决于您指定的corePoolSize

In order to submit a task with a timeout, you can just submit the task in your ThreadPoolExecutor , take the returned Future and use its timing out get(long timeout, TimeUnit unit) method: 为了提交带有超时的任务,您可以只在ThreadPoolExecutor提交任务,采用返回的Future并使用其超时get(long timeout, TimeUnit unit)方法:

Future<Result> future = pool.execute(yourTask);
Result result = future.get(30, TimeUnit.SECONDS);

You can also take a look at this related question: ExecutorService that interrupts tasks after a timeout 您还可以查看以下相关问题: ExecutorService在超时后中断任务

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM