Задание отклонено от запланированного исполнителя пула потоков после перезапуска планировщика - PullRequest
0 голосов
/ 25 января 2019

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

...