CompletableFuture получить результат без блокировки - PullRequest
0 голосов
/ 08 ноября 2018
private static boolean validateSMTP(final ArrayList mxList, String address) throws ExecutionException, InterruptedException {
  ExecutorService pool = Executors.newFixedThreadPool(mxList.size());
  List<CompletableFuture<Boolean>> allVerifiers = new ArrayList<>();
    for (int mx = 0; mx < mxList.size(); mx++) {
        CompletableFuture<Boolean> verifier = createAsyncVerifier((String) mxList.get(mx), address, pool);
        verifier.thenApply(isvalid -> isvalid);
        verifier.get();
    }
  return false;
}

В приведенном выше коде я хочу создать mxList.size() CompletableFuture, выполнить каждый. Если результатом любого из них является true Я хочу разорвать цикл, когда я использовал метод get(), который он блокирует, и я теряю выгоду от параллелизма, есть идеи о том, как это сделать?

1 Ответ

0 голосов
/ 08 ноября 2018

Вот реализация, которая отправляет все задачи, а затем получает результаты, возвращая первый true результат:

private static boolean validateSMTP(final ArrayList<String> mxList, String address)
        throws ExecutionException, InterruptedException {

    ExecutorService pool = Executors.newFixedThreadPool(mxList.size());

    return mxList.stream()
            .map(mx -> createAsyncVerifier(mx, address, pool))
            .collect(Collectors.toList())
            .stream()
            .map(CompletableFuture<Boolean>::join)
            .filter(b -> b)
            .findFirst()
            .orElse(Boolean.FALSE);
}

.collect(Collectors.toList()) обеспечивает отправку всех задач. Во втором потоке вызывается join, но это не вызывает ненужных ожиданий, поскольку все задачи уже отправлены.

findFirst вернется, как только первый элемент пройдет фильтр.

...