Вызывать метод для List параллельно? - PullRequest
3 голосов
/ 14 февраля 2020

Я должен перебрать список и вызвать для каждого объекта метод, но параллельно. После l oop появляются другие операторы, которые должны ждать параллельных вызовов методов. Как я могу сделать это в JAVA?

public void a(List<Object> list) {
    for(Object o : list) {
        asynchMethod(o); // this n method call must run in the same time
    }

    // wait for all asynchMethod result
    /**
     * ...other statements
     */
}

private void asynchMethod(Object o) {
    // some code
}

Ответы [ 3 ]

6 голосов
/ 14 февраля 2020

Я вижу, что вы используете java 8, затем вы можете использовать параллельный поток:

public void a(List<Object> list) {
    list.parallelStream().forEach(s -> asyncMethod(o));
}

, который должен ожидать параллельного вызова метода

Foreach - это терминальная операция, то есть она будет ждать завершения до перехода к следующей строке кода: Java параллельный поток: как ожидать потоков для параллельного потока до конца sh?

Если вам нужна дополнительная информация о parallelStream: https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html#executing_streams_in_parallel

Если вы хотите узнать, сколько потоков использует параллельный поток: Сколько потоков порождается в parallelStream in Java 8?

Остерегайтесь использования потоков и pararellStream, они идут со своей кучей проблем. Перед их использованием вы всегда должны внимательно изучить ситуацию и посмотреть, стоят ли они того, что они могут принести: Должен ли я всегда использовать параллельный поток, когда это возможно?

0 голосов
/ 14 февраля 2020

Использование CompletableFuture.

CompletableFuture.allOf(list.stream()
  .map(i -> CompletableFuture.submit(o -> asyncMethod(I))
  .toArray())) 
     .join();
0 голосов
/ 14 февраля 2020

Один надежный способ (из многих) параллельно выполнять любой метод - запустить пул потоков, а затем назначить ему задачи и ждать, пока задачи завершатся sh.

public static ThreadPoolExecutor getExecutorService(int poolSize, int maxPoolSize{
  int threadPoolshutDownTime = 10L;
  ThreadPoolExecutor executorService= new ThreadPoolExecutor(poolSize, maxPoolSize, threadPoolshutDownTime, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
  executorService.allowCoreThreadTimeOut(true); // allows the threadpool to shutdown if no task is assigned
  return executorService;
}

Теперь вызовите это внутри вашего метода следующим образом:

public void a(List<Object> list) throws InterruptedException, ExecutionException  {

  List<Callable<Boolean>> callables = new ArrayList<>(list.size());
  list.forEach(object ->callables.add(() -> return asynchMethod(object)));

  for (Future<Boolean> booleanFuture : this.getExecutorService(1,4).invokeAll(callables)) {
            booleanFuture.get(); //this will wait for the callables to be done!
  }
}

Также измените ваш aysncMethod следующим образом:

private boolean asynchMethod(Object o) {
    return o.doMagic(); //doMagic returns a boolean when completed
}
...