Я хочу построить планировщик, который будет периодически запускать несколько задач.Вот мой синглтон 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?Какое отношение к этому имеет проблема памяти / параллелизма?