#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
ofRunnableExample
и, следовательно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:
Используя вытягивание, было бы проще всего.
- Используйте синглтон, чтобы иметь один и тот же общий объект между двумя потоками.
- Используйте блокировку l ведьма используется для ввода любого из 3 методов.
a. hasMessage() (посмотрите в список)
b. GetMessage() (выйти из списка)
c. putMessage(элемент объекта) (добавить элемент в список)
Всякий раз, когда основной поток готов (например, каждые 100 итераций), он проверяет, является ли hasMessage() истинным.