ScheduledExecutorService с форматом знакомства, добавленным в ActionListener - PullRequest
1 голос
/ 31 марта 2020

Я понимаю, что в Java можно использовать ScheduledExecutorService для выполнения определенной c задачи после некоторой задержки. Этот пост показывает, как выполнить задачу в конкретную c дату, но не с SimpleDateFormat. Например, у меня есть формат, инициализированный, как показано ниже:

dateFormatter = new SimpleDateFormat("MM-dd-yyyy hh:mm aa");

Кроме того, я хочу выполнить определенную задачу, объявленную в операторе else if в ActionListener, например ниже:

foo.addActionListener(e -> {
            if (condition) {

            // some task

            } else if (some other condition) { // what I want to be executed at particular date

            // some other task

            } else {

            // another task

            }
        });

Как можно инициализировать ScheduledExecutorService, который выполняется внутри и / или с оператором else if на определенную дату, предпочтительно с SimpleDateFormat?

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Establi sh служба исполнителя ранее

Как можно инициализировать ScheduledExecutorService, который выполняется внутри и / или с помощью else, если

Вы не делаете.

Не инициализируйте службу исполнителя в том месте, где она вам нужна.

Вы создаете экземпляр службы по расписанию в другом месте ранее, сохраняя ссылку в именованной переменной. При необходимости вызовите этот объект службы исполнителя.

Эта служба исполнителя может быть вызвана для запуска других видов задач в других частях вашего приложения. Служба исполнителя не должна быть привязана только к одной задаче.

Важно Необходимо сохранить ссылку на эту службу исполнителя, чтобы ее резервный пул потоков можно было аккуратно закрыть в какой-то момент. В противном случае пул потоков может продолжить работу после завершения его исходного приложения.

Обычно я предлагаю такой подход.

  • Когда приложение запускает , устанавливает sh службу вашего исполнителя. Сохраните ссылку для последующего доступа через ваш выбор глобальной переменной. Возможно Singleton или Service Locator или внедрение зависимостей , например , передаваемое конструктору .
  • Во время ваше приложение запускает , найдите эту существующую службу исполнителя. Отправьте задачу на выполнение.
  • Когда приложение завершает работу , найдите эту существующую службу исполнителя. Вызовите его метод завершения, чтобы завершить пул вспомогательных потоков.

Переполнение стека поиска. Эта топика c была освещена много раз. Вы найдете пример кода и дальнейшее обсуждение.

Пример кода

Используйте служебный класс Executors для создания экземпляра службы исполнителя.

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor() ; 

Сохраните ссылку ses где-нибудь в ваше приложение.

Рассчитайте время ожидания, как показано в правильном ответе Ole VV

foo.addActionListener(
    e -> {
        if (condition) {

            doSomethingNow() ;

        } else if (some other condition) { 

            long delaySeconds = … ;  // See: https://stackoverflow.com/a/60963540/642706
            ScheduledExecutorService scheduledExecutorService = Objects.requireNonNull​( … ) ;  // Locate the existing scheduled executor service.
            Runnable task = () -> { System.out.println( "Doing something later. " + Instant.now() ) ; };
            scheduledExecutorService.schedule(
                task ,
                delaySeconds ,
                TimeUnit.SECONDS
            );

        } else {

            doSomethingElseNow() ;

        }
    }
);

Когда ваше приложение завершает работу, закройте службу запланированного исполнителя .

// In the hook for app shut-down.
ScheduledExecutorService scheduledExecutorService = Objects.requireNonNull​( … ) ;  // Locate the existing scheduled executor service.
scheduledExecutorService.shutdown() ;
2 голосов
/ 01 апреля 2020

java .time

Используйте java .time, современный Java API даты и времени для вашей работы с датой и временем. Современный класс для использования вместо старого SimpleDateFormat - это DateTimeFormatter.

static DateTimeFormatter formatter
        = DateTimeFormatter.ofPattern("MM-dd-yyyy hh:mm a", Locale.ENGLISH);

Редактировать: как сказал в комментарии Василий Бурк, также объявите службу поддержки где-нибудь, где вы можете закрыть ее, когда вы не больше нужно. Например:

static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

Теперь в вашем слушателе действий (или любом другом месте, которое вам может понравиться) вы можете сделать:

        } else {
            String timeString = "04-01-2020 08:00 AM";
            ZoneId zone = ZoneId.of("America/Curacao");
            ZonedDateTime timeToExecute = LocalDateTime.parse(timeString, formatter)
                    .atZone(zone);
            long delaySeconds = ChronoUnit.SECONDS.between(
                    ZonedDateTime.now(zone), timeToExecute);
            executor.schedule(() -> System.out.println("It’s now " + timeString),
                            delaySeconds, TimeUnit.SECONDS);
        }

Не забудьте закрыть исполнителя, чтобы освободить ресурсы вызов

    executor.shutdown();

Или, если вы хотите отменить уже запланированные задачи, используйте вместо этого shutdownNow().

Я установил довольно случайные значения для желаемого времени и часового пояса, поэтому, пожалуйста, введите ваши значения вместо. Если вам нужна настройка часового пояса вашей JVM, опция ZoneId.systemDefault() является опцией.

Среди многих других преимуществ java .time имеет лучшую поддержку для вычисления продолжительности временного интервала с настоящего момента до желаемого запланированного время. Если вам требуется точность выше, чем вторая, используйте вместо этого миллисекунды, микросекунды или даже наносекунды, то это будет происходить очень похоже (поскольку ваша строка, кажется, имеет только незначительную точность, я не думаю, что это было необходимо).

Упомянутый вами SimpleDateFormat является печально известным нарушителем класса, вы никогда не будете его использовать. К счастью, он также давно устарел.

Ссылка

Oracle учебное пособие: Дата и время , объясняющее, как использовать java .time.

...