我有一个线程池:
ThreadPoolExecutor pool = new ThreadPoolExecutor(cores, 50, 30L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3000));
然后我跑:
try {
pool.execute(() ->
{
//Very very long task, fetching from an external URL
});
}catch(Exception e){
e.printStackTrace();
}
我永远不会得到异常,这段代码会等待几分钟。 我应该怎么做才能在30秒内取消?
答案 0 :(得分:5)
根据文档,第3个参数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.
对于您想要的行为,您应该将任务包装在 FutureTask 中,然后将未来任务提交给线程池。在未来的任务中,您可以调用 get(timeout,timeunit)
FutureTask<T> task = new FutureTask<T>(c);
pool.execute(task);
return task.get(timeout, timeUnit);
答案 1 :(得分:1)
您指定为30秒的是执行程序的空闲线程的keepAliveTime
。这是当前未处理任务的多余线程将保持活动的持续时间。这里多余的线程被定义为除了每个核心的一个线程之外创建的线程,ThreadPoolExecutor
将保持活动状态,具体取决于您指定的corePoolSize
。
要提交超时的任务,您只需在ThreadPoolExecutor
中提交任务,获取返回的Future
并使用其超时get(long timeout, TimeUnit unit)
方法:
Future<Result> future = pool.execute(yourTask);
Result result = future.get(30, TimeUnit.SECONDS);
您还可以查看以下相关问题:ExecutorService that interrupts tasks after a timeout