Избегайте запланированного исполнителя от создания нескольких экземпляров процесса Java

Я создал запланированную задачу, которая выполняет вызов внешнего .jar, который создает несколько файлов xml, я хочу, чтобы это запускалось каждые 4 минуты. Каждый раз, когда запускается внешний .jar, создается новый экземпляр, но я хочу, чтобы он закрыл существующий и вместо этого создал новый.

в основном это мой код:

private static void RunInvoiceProcesses(Properties props) {
ScheduledExecutorService executorService =  
Executors.newScheduledThreadPool(executorService.scheduleAtFixedRate(new 
Runnable() {
        @Override
        public void run() {

          Runtime.getRuntime().exec("cmd /c call C:\\creinvoice\\XMLGen\\runxmlgen.bat");


        }
},
15,
240,
TimeUnit.SECONDS);

// .bat просто вызывает java -jar myapp.jar

и это тот, который должен запускаться только по одному экземпляру за раз. каждый раз, когда этот runnable запускается, он вызывает летучую мышь, и JVM создает новый экземпляр.

Я попытался создать экземпляр процесса вне исполнителя и сделать что-то вроде этого

Process xmlGeneration = null;

  Runnable() {
        @Override
        public void run() {
    if (xmlGeneration.stillAlive()){xmlGeneration.Destroy();}
         xmlGeneration= Runtime.getRuntime().exec("cmd /c call C:\\creinvoice\\XMLGen\\runxmlgen.bat");


        }
}

но кажется, что вы можете внести в runnable только конечные переменные, так что это невозможно. Конечно, я пытался изучить все, что мог об этом, но если вы можете хотя бы указать мне правильное направление, где искать, я был бы очень признателен!

Я также обнаружил, что некоторые люди привязывают экземпляр приложения к ServerSocket, чтобы добиться чего-то похожего на то, что я пытаюсь сделать, но я не уверен, что это безопасный подход, какие-либо рекомендации?

Juan Felipe 25.02.2019 03:17
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
158
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из Javadoc

If any execution of this task * takes longer than its period, then subsequent executions * may start late, but will not concurrently execute.

Так что вам просто нужно дождаться завершения процесса в вашем runnable примерно так:

Process p =  Runtime.getRuntime().exec(...);
p.waitFor();

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

Я только что проверил это, и, похоже, это решение этой проблемы. Большое спасибо!

Juan Felipe 25.02.2019 07:45

Другие вопросы по теме