#java #multithreading
#java #многопоточность
Вопрос:
Как мне назначить Status
с CallMe()
помощью isFinish()
, чтобы возвращаемое значение было истинным?
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;
}
Комментарии:
1. Зачем вообще использовать поток? Start() создаст отдельный поток выполнения, и в этот момент isFinish продолжит его выполнение.
Ответ №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();
- Использование класса holder
Вы создаете класс, содержащий значение, и предоставляете ссылку на этот класс. Вы можете создать свой собственный класс или просто использовать AtomicReference
. Под классом holder я подразумеваю класс, который имеет общедоступный изменяемый атрибут.
// 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();
Комментарии:
1. 1, как два метода, действительно спасибо. Мне нужно было иметь полнодуплексный режим, который дает мне наилучшее направление.
2. Спасибо! Мне это было нужно для моего университетского проекта, вы очень помогли.
Ответ №2:
Вы переписываете код для использования Callable<Boolean>
и получаете a Future
при запуске Runnable
.
Фьючерсы позволяют запускающему потоку правильно проверять готовность значения и считывать его асинхронно. Вы могли бы выполнить кодирование вручную, но поскольку Future
теперь оно является частью стандартных библиотек JVM, зачем вам это (вне класса программирования)?
Ответ №3:
Работая с необработанными потоками, вы могли бы реализовать Runnable с именованным типом и сохранить в нем значение.
class MyRunnable implements Runnable {
boolean status;
public void run() {
...
}
}
Однако, если вы работаете с другим потоком, вам придется каким-то образом синхронизировать.
Было бы проще использовать инструменты более высокого уровня, предоставляемые иерархией java.util.concurrent. Вы можете отправить вызываемый объект исполнителю и получить будущее. Вы можете спросить будущее, сделано ли это, и получить результат. Здесь есть руководство по Oracle.