Java, дождитесь завершения дочернего процесса - PullRequest
3 голосов
/ 07 января 2011

Использование Java ProcessBuilder Я создаю группу дочерних процессов. Я могу использовать метод waitFor() из получающегося объекта Process, чтобы дождаться выхода этого конкретного потомка.

Можно ли заблокировать до любого дочернего выхода, как системный вызов UNIX wait()?

Ответы [ 3 ]

9 голосов
/ 07 января 2011

Первый шаг - представить работу, выполненную каждым подпроцессом, как Future , например:

final ProcessBuilder builder = ...;

// for each process you're going to launch
FutureTask task = new FutureTask(new Callable<Integer>() {
  @Override public Integer call() {
    return builder.start().waitFor();
  }
};

Теперь отправьте все задания исполнителю:

ExecutorService executor = Executors.newCachedThreadPool();
for (FutureTask task : tasks) {
  executor.submit(task);
}

// no more tasks are going to be submitted, this will let the executor clean up its threads
executor.shutdown();

Теперь используйте отличный ExecutorCompletionService класс:

ExecutorCompletionService service = new ExecutorCompletionService(executor);
while (!executor.isTerminated()) {
  Future<Integer> finishedFuture = service.take();
  System.out.println("Finishing process returned " + finishedFuture.get());
}

Этот цикл будет повторяться один раз для каждой завершающей задачи по завершении. returnValue будет кодом завершения дочернего процесса.

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

Да, и, конечно, если вас не волнует ожидание всех заданий, вы можете просто позвонить take() один раз.

0 голосов
/ 07 января 2011

Вы должны использовать некоторую форму IPC для достижения этой цели. Если вам разрешено использовать нативные библиотеки и вы работаете на платформе UNIX / Linux, попробуйте использовать тот же системный вызов wait (), написав простую оболочку JNI и вызвав нативный метод из кода Java.

Если вы не можете использовать собственные механизмы IPC, используйте механизм сервер / клиент TCP / IP, в котором вы управляете выходом дочернего процесса с сервера, пока клиент подключается к серверу или отсоединяется от него. Если нет дочерних соединений, вы можете выйти из программы сервера!

0 голосов
/ 07 января 2011

Читать о CountDownLatch

CountDownLatch инициализируется с учитывая количество. Блок методов ожидания пока текущий счетчик не достигнет нуля из-за вызовов countDown () метод, после которого все ждут темы освобождаются и любые последующие вызовы ожидают возвращения немедленно. Это один выстрел явление - считать нельзя сброс. Если вам нужна версия, которая сбрасывает счет, рассмотрите возможность использования CyclicBarrier.

...