我想构建一个计划程序,该程序将定期运行多个任务。这是我的SchedulerExecutor单例,它执行2个操作,开始和停止。 SchedulerProperty拥有一些基本属性,例如初始延迟,连续延迟,超时秒数等。
public class SchedulerExecutor {
private static SchedulerExecutor ourInstance = new SchedulerExecutor();
public static SchedulerExecutor getInstance() {
return ourInstance;
}
private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private final TaskManager taskManager = new TaskManager();
private final SchedulerService schedulerService = new SchedulerService();
private SchedulerExecutor() { }
public void startScheduler() throws Exception {
SchedulerProperty property = schedulerService.getCurrentSchedulerProperty();
if(property.isRunning()){
throw new RequestFailureException("Scheduler is Already Running");
}
property.setRunning(true);
property.setLastRunningTime(Instant.now().toEpochMilli());
schedulerService.updateSchedulerProperty(property);
log.info("Scheduler is Running");
executorService.scheduleAtFixedRate(taskManager::runPendingTask, property.getInitialDelay(), property.getSuccessiveDelay(), TimeUnit.SECONDS);
}
public void stopScheduler() throws Exception {
SchedulerProperty property = schedulerService.getCurrentSchedulerProperty();
if(!property.isRunning()) {
throw new RequestFailureException("Scheduler is Already Terminated");
}
executorService.shutdown();
try {
if(!executorService.awaitTermination(property.getTimeoutForTermination(), TimeUnit.SECONDS)){
executorService.shutdownNow();
}
} catch (InterruptedException e) {
log.fatal(e.getMessage());
executorService.shutdownNow();
}
property.setRunning(false);
schedulerService.updateSchedulerProperty(property);
log.info("Scheduler has terminated");
}
}
计划程序将定期运行Taskmanager类的暂挂任务方法。这是我的Taskmanager类
public class TaskManager {
private final static AtomicInteger atomicInteger = new AtomicInteger(1);
public void runPendingTask() {
log.info(atomicInteger.getAndIncrement() + " Running Pending Task");
ExecutorService executorService = Executors.newScheduledThreadPool(5);
TaskService taskService = new TaskService();
List<Task> pendingTasks = taskService.getPendingTasks();
pendingTasks.forEach(t->
executorService.execute(()->{
log.info("Pending Task: " + t.getTaskName());
}, )
);
}
}
问题是,此代码在我第一次启动调度程序时运行良好。它定期在日志中打印消息。但是每当我停止调度程序然后重新启动它时,它就会出现以下异常
Task java.util.concurrent.SchedulerThreadPoolExecutor$ScheduledFutureTask
@318af76f rejected from
java.util.concurrent.ScheduledThreadPoolExecutor
@2b0847be[Terminated, pool size=0, active threads=0, queued task=0, completed tasks=1]
这是什么解决方案? 我还应该移动
ExecutorService executorService = Executors.newScheduledThreadPool(5);
在TaskManager类内部而不是runPendingTask方法?关于此的内存问题/并发问题是什么?