2016-05-02 9 views
1

Объект Java Future используется для получения результата асинхронного вычисления, выполняемого параллельным потоком (исполнителями). Мы называем метод Future.get() и ожидаем, пока результат не будет готов. В этом примере показан неблокирующий способ получения результата из Future. java-implement-java-non-blocking-futures.Как реализовать неблокирующие фьючерсы в Java

NonBlockingExecutor executor = new NonBlockingExecutor(Executors.newSingleThreadExecutor()); 

NonBlockingFuture<Integer> future = executor.submitNonBlocking(new Callable<Integer>() { 

      @Override 
      public Integer call() throws Exception { 
       String threadName = Thread.currentThread().getName(); 
       System.out.println(threadName); 
       //print -> pool-1-thread-1 
       return 1; 
      } 
}); 

future.setHandler(new FutureHandler<Integer>() { 

     @Override 
     public void onSuccess(Integer value) { 
      String threadName = Thread.currentThread().getName(); 
      System.out.println(threadName); 
      //print -> pool-1-thread-1 
     } 

     @Override 
     public void onFailure(Throwable e) { 
      System.out.println(e.getMessage()); 
     } 
}); 

Thread.sleep(50000); 

В этом методе onSuccess() вызывается после завершения параллельного выполнения. Проблема заключается в том, что метод onSuccess() не работает в основном потоке. Я хочу выполнить метод onSuccess() в основном потоке. Как я могу это исправить. Спасибо

+1

Предположительно, ваш основной поток занят чем-то другим. –

+0

Честно говоря, я не знаю, как это сделать с исполнителями. Сбой во всем остальном, вы всегда можете «взломать» его в виду - просто передайте некоторые данные в коллекцию, затем основной поток видит данные в этой коллекции и отвечает соответствующим образом. – KookieMonster

+0

Можем ли мы это сделать, используя Java 8 CompletableFuture? – Tharanga

ответ

1

Точка Future состоит в том, что соответствующее вычисление выполняется в отдельном потоке. Метод onSuccess является способом для этого отдельного потока сказать, что он завершил выполнение вычисления. Для основного потока нет смысла вызывать onSuccess, так как основной поток не выполняет вычисления и не знает, когда вычисление будет завершено.

Из основного потока, если вы хотите дождаться завершения вычисления и получить результат, позвоните по номеру get(). Если вы хотите проверить, завершено ли вычисление и продолжать делать другие вещи, если оно еще не завершено, вызовите isDone() или get(long, TimeUnit). Если вы хотите завершить вычисление, завершено или нет, позвоните по номеру cancel().

+1

спасибо. Да, вы правы, но get() - операция блокировки. Мы можем сделать это, используя CompletableFuture, но снова столкнулись с одной и той же проблемой. Результатом является не процесс в основном потоке. [CompletedFuture] (http://stackoverflow.com/questions/36981432/why-completablefuture-s-thenaccept-not-running-on-the-main-thread) – Tharanga

+0

Другие варианты, о которых я упоминаю, являются неблокирующими или только блоками для ограниченного время. –

1

Я хочу выполнить onSuccess() метод на основной теме. Как я могу это исправить.

Вы не можете. Ничто в Java не может заставить поток остановить то, что он делает, сделать что-то еще на мгновение, а затем вернуться к тому, что он делает. Некоторые среды программирования имеют такую ​​особенность --- Unix сигналы, аппаратные средства interrupts --- Но это просто не язык Java.

1

Это поддерживается с помощью CompletableFutures.

CompletableFuture.runAsync(() -> { 
     String threadName = Thread.currentThread().getName(); 
     System.out.println(threadName); 
     //print -> pool-1-thread-1 
    }).whenComplete((task, throwable) -> { 
     if(throwable != null) { 
      System.out.println(e.getMessage()); 
     } else { 
      String threadName = Thread.currentThread().getName(); 
      System.out.println(threadName); 
      //print -> pool-1-thread-1 
     } 
    }); 

Оговорки здесь является то, что будущий будет запускать whenComplete задачи на выполняющийся потоке, а не подающие нити.