Как я могу выполнить определенную задачу в основном потоке на основе ответа от другого потока?

#java #multithreading #java.util.concurrent

Вопрос:

Основной поток(RunnableTest) не должен ждать завершения другого потока(пример выполнения), чтобы выполнить цикл для печати чисел от 0 до 4. Основной поток и другой поток будут выполняться параллельно. После получения результата, возвращенного из другого потока, основной поток снова будет находиться в режиме действия. Как я могу этого достичь?

У меня есть основная тема, как показано ниже:

 public class RunnableTest {
    public static void main(String[] args) {
        //some code
        new RunnableExample();
        for (int i = 0; i < 5; i  ) {
            System.out.println(i);
        }
        // Upon receiving result from RunnableExample thread again main thread will be in action and perform some task
    }
}
 

Другой поток, выполняющий определенную задачу:

 public class RunnableExample implements Runnable {
    boolean isAvailable = false;
    Thread thread;

    public RunnableExample() {
        thread = new Thread(this);
        thread.start();
    }

    public void run() {
        isAvailable = checkForAvailability();
    }

    private boolean checkForAvailability() {
        // some task
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
        }
        return true;
    }
}
 

Комментарии:

1. в чем заключается вопрос?

2. Локальный поток, созданный в конструкторе of RunnableExample , не использует метод run of RunnableExample и, следовательно checkForAvailability , также НЕ вызывается. Этот поток должен был быть объявлен как: public RunnableExample() { new Thread(this).start();}

3. @AlexRudenko метод запуска будет выполнен, когда thread.start() будет выполняться внутри конструктора RunnableExample (). И я создаю объект класса RunnableExample внутри класса RunnableTest.

4. @Srikant, нет, это не так. Экземпляр RunnableExample (реализации Runnable ) не был предоставлен экземпляру потока, запущенного в конструкторе.

5. @AlexRudenko Извини за мою ошибку!! Он обновлен

Ответ №1:

Как я могу выполнить определенную задачу в основном потоке на основе ответа от другого потока?

Если я правильно понимаю ваш вопрос, ответ заключается в использовании thread.join(); . Когда вы разветвляете свой RunnableExample поток от основного потока, они оба выполняются параллельно, но затем основной поток должен дождаться другого потока, прежде чем продолжить.

 // this just creates the object, it doesn't start the thread
RunnableExample example = new RunnableExample();
// create the thread object with the example as the Runnable
Thread thread = new Thread(example);
// start the thread running, it will call RunnableExample.run()
thread.start();
// now main does what it needs to do in parallel with the background thread
for (int i = 0; i < 5; i  ) {
   ...
}
// later it should join on background thread, it will wait for it to finish
thread.join();
// it then can read any fields from the example object
System.out.println("isAvailable = "   example.isAvailable);
 

Важно понимать, что без join() вызова основной поток не сможет получить доступ к example.isAvailable полю, поскольку память не была синхронизирована. После join() возврата основной поток гарантированно example обновит память соответствующим образом.

Ответ №2:

Используя вытягивание, было бы проще всего.

  1. Используйте синглтон, чтобы иметь один и тот же общий объект между двумя потоками.
  2. Используйте блокировку l ведьма используется для ввода любого из 3 методов.

    a. hasMessage() (посмотрите в список)

    b. GetMessage() (выйти из списка)

    c. putMessage(элемент объекта) (добавить элемент в список)

Всякий раз, когда основной поток готов (например, каждые 100 итераций), он проверяет, является ли hasMessage() истинным.