Как да предотвратим изпълняването на класа CompletableFuture?

+8 гласа
89 прегледа
попитан 2016 април 1 от Rado.T. (1,360 точки)

Знам,че дизайнът CompletableFuture не може да контролира изпълнението си с прекъсвания (interruptions), но предполагам някои от вас са имали подобен проблем. CompletableFutures са много добър начин за правене на асинхронизирани execution-и, но в случая когато трябва изпълняването да има прекъсвания или спирания когато future-а е отменен (cancel-нат), как се справяме в тази ситуация?

Това очевидно е ненужна работа, която отнема много време... но се чудих какъв подход бихте ме съветвали да избера ...или дизайн, който може да помогне в този случай?

Ето и един пример:

public class SimpleTest {

  @Test
  public void testCompletableFuture() throws Exception {
    CompletableFuture<Void> cf = CompletableFuture.runAsync(()->longOperation());

    bearSleep(1);

//    cf.cancel(true);
    cf.complete(null);

    System.out.println("it should die now already");
    bearSleep(7);
  }

  public static void longOperation(){
    System.out.println("started");
    bearSleep(5);
    System.out.println("completed");
  }

  private static void bearSleep(long seconds){
    try {
      TimeUnit.SECONDS.sleep(seconds);
    } catch (InterruptedException e) {
      System.out.println("OMG!!! Interrupt!!!");
    }
  }
}

1 отговор

+1 глас
отговорени 2016 април 4 от Daniel Ivanov (11,160 точки)

CompletableFuture няма общо с асинхронизиранизираните действия, които могат евентуално да се изпълнят.

Тъй като (за разлика от FutureTask) този клас няма директен контрол над изчислението, което е отговорно за изпълнението, спирането се възприема като друга форма на изключително изпълнение или т.н. exceptional completion. Методът cancel  има същия ефект като completeExceptionally(new CancellationException()).

Може изобщо да няма отделен thread,който да работи над изпълняването му (може даже да няма много thread-ове,които да работят над него). Дори и да има, няма линк от CompletableFuture към какъвто и да е thread, който да има референция към него.

Тъй че нищо не можеш да направиш по въпроса като използваш CompletableFuture да предотвратяваш някакъв thread, който да го изпълнява. Трябва да си измислиш сам някакъв начин,който да track-ва някакви инстанции на  Thread-а ,който съдържа референция към CompletableFuture без да имаш прекъсвания.

...