CompletableFuture anyOf - PullRequest
       52

CompletableFuture anyOf

0 голосов
/ 05 мая 2020

Итак, раньше у меня был экзамен, и был этот вопрос.

Вопрос 5: Асинхронное программирование (8 баллов)

Рассмотрим программу ниже. Метод doSomething ( ) может выполняться в течение неопределенного c количества времени.

import java.util.concurrent.CompletableFuture;
class CF {
  static void doSomething() { .. }
  
  static CompletableFuture<Void> printAsync(int i) {
    return CompletableFuture.runAsync(() -> {
        doSomething();
        System.out.print(i);
    });
  }

  public static void main(string[] args) {
    CompletableFuture.anyof(
         printAsync(1)
           .thenRun(() -> printAsync(2)),
         printAsync(3))
      .thenRun(() -> printAsync(4));
    dosomething();
  }
}

Какие возможные результаты выводит программа, если main выполняется до завершения нормально?

Заполнить пробел со строкой да, если данный вывод возможен. Заполните пустое поле строкой no, если main никогда не распечатает данный вывод. Обратите внимание, что этот вопрос будет оцениваться ботом. Таким образом, если заполнить любой другой текст, например «НЕТ!», «Да, потому что…», «Никогда!» И т. Д. c, ответ будет отмечен как неправильный, даже если цель ответа правильно.

(а) 1 (Би 2 (c) 3 (г) 4 (д) 12 (е) 14 (г) 23 (ч) 24 (i) 124 (j) 134 (к) 243 (л) 234 (м) 213 (п) 1324 (o) 4321

Мой вопрос для CompletableFuture.anyOf. Когда один из процессов завершается sh, завершается ли другой процесс sh до завершения даже после того, как другой thenRun выполняется, или он завершается преждевременно?

1 Ответ

1 голос
/ 05 мая 2020

anyOf создает только новое будущее, позволяющее запланировать другие операции, которые будут выполняться, когда хотя бы один из указанных фьючерсов будет завершен. Он не влияет ни на один из его аргументов.

Но обратите внимание, что основной метод использует его только для цепочки другой операции, не дожидаясь завершения какого-либо будущего. Он просто выполняет еще один doSomething(), что занимает специально не указанное время. Затем возвращается метод main, и в стандартной среде JVM завершает работу, когда обнаруживает, что существуют только потоки демона.

Поскольку это завершение JVM не влияет на какие-либо фоновые операции, существует нет гарантии по поводу завершения. В принципе, даже вывод невозможен.

Но связанные операции определяют зависимости, которым подчиняются.

  1. 1 → 2. Следовательно, вы никогда не увидите 2 без 1 в выводе. И когда присутствуют оба числа, 1 должно быть перед 2.
  2. (1 → 2 | 3) → 4. Если вы видите 4, должно быть хотя бы одно из 2 или 3, и оно должно быть до 4. Когда это 2, применяется и первый пункт. Но обратите внимание, что когда присутствуют оба, 2 и 3, только один из них должен быть перед 4, поэтому 3412 будет допустимым выходом.

Помимо этих правил, порядок может быть произвольным, и, как сказано, завершение не гарантируется. Вы могли увидеть подошву 1 или подошву 3, или 1 и 3 в произвольном порядке. Но, как объяснялось выше, вы не можете увидеть подошву 2 или подошву 4. Вы можете набрать go в каждом предложенном ответе и проверить, не нарушает ли он одну из зависимостей. Если нет, то это возможный исход.

...