我们需要在ScheduledExecutorService上调用awaitTermination吗?

时间:2015-04-09 16:31:40

标签: java multithreading

您好我是Java多线程的新手。我有成千上万的计划任务/线程需要执行。我使用以下代码

ScheduledExecutorSerivce scheduleService = Executors.newScheduledThreadPool(90);
Map<Interger,Interger> loginMap = new HashMap<>();//contain login time of scheduled threads
for(int i = 0; i < taskCount ; i++) {
  scheduleService.schedule(new MyCallableWorker(),loginMap.get(i),TimeUnit.SECONDS)
}
scheduleService.shutdown();
//do I need to call the following because I dont know any timeout value or above shutDown() is enough
while(!scheduleService.isTerminated()) {
}

另外请告诉我什么应该是线程池的理想计数。我已设置为90但我想要可以根据需要增长的池,但看起来像ScheduleExecutorService没有这样的API。请提前指导谢谢。

2 个答案:

答案 0 :(得分:4)

scheduleService.shutdown();

将指示不应该接受新任务的调度程序和现有的任务将被取消或者可以执行(但不会重复),具体取决于所使用的策略:

  

“如果已设置ExecuteExistingDelayedTasksAfterShutdownPolicy   错误的现有延迟任务,其延迟尚未过去   取消。除非   ContinueExistingPeriodicTasksAfterShutdownPolicy已设置为true,   将来执行现有的定期任务将被取消。“

现在在您的代码中,您应该致电:

scheduleSerice.awaitTermination()

而不是while(!scheduleService.isTerminated())。 while循环将烧毁处理器的所有周期,因为它将不断检查执行程序状态。

如果你没有调用awaitTermination方法(或你的循环aproach),你调用shceduleService.schedule的方法将完成(退出),并且可能你的整个程序将终止(不完成作业)。

但这取决于你的设计。如果它是异步的,那么你可以简单地忽略awaitteration并继续你的工作。这些工作将在后台处理。

您的线程池不应该增长!!!! 它应该与您的avaialbe资源== CPU匹配。对于正在等待资源的IO任务,它应该在处理器计数周围,对于IO任务来说,CPU的数量加倍,任何更多的事情都没有意义,它实际上会减慢执行速度,因为会有线程数据。

池大小限制了同时执行的任务数量,而不是任务队列的大小,除非另外设置,否则它将无限制地增长。

答案 1 :(得分:2)

如果您的应用程序在确保所有当前任务完成后应该执行某些操作,则需要调用awaitTermination()。如果您的应用程序不关心当前任务何时完成,那么您不需要awaitTermination()

关于增加线程池大小,您可以直接使用ScheduledThreadPoolExecutor

/**
 * Creates a new {@code ScheduledThreadPoolExecutor} with the
 * given core pool size.
 *
 * @param corePoolSize the number of threads to keep in the pool, even
 *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
 * @throws IllegalArgumentException if {@code corePoolSize < 0}
 */
public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
          new DelayedWorkQueue());
}

将核心池大小保持为最低限度,并使其增长到最大池大小。