Подтвердить что ты не робот

Как получить возвращаемое значение из внутреннего метода Runnable Thread в Java?

Как назначить Status с помощью CallMe(), используя isFinish(), чтобы вернуть значение true?

public static boolean isFinish ()
{    
  boolean Status = false;
  new Thread(new Runnable()
  {
    public void run()
    {
      /* This shell return true or false 
       * How do you keep it in Status
       */
      CallMe(); 
    }
  }).start();

  /* How can i get the true or false exactly from CallMe? here */
  return Status;
}

public static boolean CallMe()
{
  /* some heavy loads ... */
  return true;
}
4b9b3361

Ответ 1

Есть два способа сделать это. Во-первых, использовать результат вычисления в будущем, а другой - иметь общую переменную. Я думаю, что первый метод намного чище, чем второй, но иногда вам нужно также вводить значения в поток.

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

FutureTask реализует RunnableFuture. Таким образом, вы создаете эту задачу, которая после выполнения будет иметь значение.

RunnableFuture f = new FutureTask(new Callable<Boolean>() {
  // implement call
});
// start the thread to execute it (you may also use an Executor)
new Thread(f).start();
// get the result
f.get();
  • Использование класса держателя

Создается класс, содержащий значение и передающий ссылку на этот класс. Вы можете создать свой собственный класс или просто использовать AtomicReference. По классу держателя я имею в виду класс, который имеет общедоступный изменяемый атрибут.

// create the shared variable
final AtomicBoolean b = new AtomicBoolean();
// create your thread
Thread t = new Thread(new Runnable() {
  public void run() {
    // you can use b in here
  }
});
t.start();
// wait for the thread
t.join();
b.get();

Ответ 2

Вы переписываете код для использования Callable<Boolean> и получаете Future при запуске Runnable.

Фьючерсы позволяют запускающему потоку правильно проверять, что значение готово, и читать его асинхронно. Вы можете сделать кодирование вручную, но поскольку Future теперь является частью стандартных библиотек JVM, почему бы вам (вне класса программирования)?

Ответ 3

Работая с необработанными потоками, вы можете реализовать Runnable с именованным типом и сохранить в нем значение.

class MyRunnable implements Runnable {
   boolean status;

   public void run() {
      ...
   }
}

Однако, если вы работаете с другим потоком, вам придется каким-то образом синхронизировать.

Было бы проще использовать инструменты более высокого уровня, предоставляемые иерархией java.util.concurrent. Вы можете отправить Подписываемую Исполнительу и получить Будущее. Вы можете спросить Будущее, если это будет сделано, и получить результат. Там учебник Oracle здесь.