Java Runnable run() метод, возвращающий значение
В соответствии с java doc метод Runnable
void run()
не может вернуть значение. Однако я задаюсь вопросом, есть ли какое-либо обходное решение.
На самом деле у меня есть метод, который вызывает:
public class Endpoint{
public method_(){
RunnableClass runcls = new RunnableClass();
runcls.run()
}
}
wheren run()
:
public class RunnableClass implements Runnable{
public jaxbResponse response;
public void run() {
int id;
id =inputProxy.input(chain);
response = outputProxy.input();
}
}
Я хочу иметь доступ к переменной response
в method_()
, возможно ли это?
Ответы
Ответ 1
Используйте Callable<V>
вместо использования интерфейса Runnable
.
Пример:
public static void main(String args[]) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(3);
Set<Future<Integer>> set = new HashSet<Future<Integer>>();
for (String word: args) {
Callable<Integer> callable = new WordLengthCallable(word);
Future<Integer> future = pool.submit(callable);
set.add(future);
}
int sum = 0;
for (Future<Integer> future : set) {
sum += future.get();
}
System.out.printf("The sum of lengths is %s%n", sum);
System.exit(sum);
}
В этом примере вам также понадобится реализовать класс WordLengthCallable, который реализует интерфейс Callable.
Ответ 2
public void check() {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> result = executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return 10;
}
});
try {
int returnValue = result.get();
} catch (Exception exception) {
//handle exception
}
}
Ответ 3
Посмотрите на класс Callable. Обычно это отправляется через службу
Он может возвращать будущий объект, который возвращается, когда поток завершается
Ответ 4
Если вы добавите поле в RunnableClass
, вы можете установить его в run
и прочитать его в method_
. Однако Runnable
является плохим (ключевое слово Java) interface
, поскольку он ничего не говорит о интерфейсе (концепции) (только полезная строка API-документов: "Общий контракт метода run
заключается в том, что он может предпринимать какие-либо действия".). Намного лучше использовать более значимый интерфейс (который может что-то вернуть).
Ответ 5
В одном случае мы должны использовать подход Future - Callable
.
Другой способ: вместо возврата значения можно сохранить в объекте
Пример:
class MainThread {
public void startMyThread() {
Object requiredObject = new Object(); //Map/List/OwnClass
Thread myThread = new Thread(new RunnableObject(requiredObject)).start();
myThread.join();
System.out.println(requiredObject.getRequiredValue());
}
}
class RunnableObject implements Runnable {
private Object requiredObject;
public RunnableObject(Object requiredObject) {
this.requiredObject = requiredObject;
}
public void run() {
requiredObject.setRequiredValue(xxxxx);
}
}
Поскольку область объекта находится в одной области, поэтому вы можете передать объект потоку и получить его в основной области. Но самое главное, мы должны использовать метод join(). Потому что основная область должна ждать завершения потока своей задачи.
Для случая с несколькими потоками вы можете использовать List
/Map
для хранения значений из потоков.
Ответ 6
Взгляните на вызываемый интерфейс, возможно, это соответствует вашим потребностям. Вы также можете попытаться получить значение поля ответа, вызвав метод setter внутри вашего метода run()
public void run() {
int id;
id =inputProxy.input(chain);
response = outputProxy.input();
OuterClass.setResponseData(response);
}
Ответ 7
Да, есть обходной путь. Просто используйте очередь и введите в нее значение, которое вы хотите вернуть. И возьмите это значение из другого потока.
public class RunnableClass implements Runnable{
private final BlockingQueue<jaxbResponse> queue;
public RunnableClass(BlockingQueue<jaxbResponse> queue) {
this.queue = queue;
}
public void run() {
int id;
id =inputProxy.input(chain);
queue.put(outputProxy.input());
}
}
public class Endpoint{
public method_(){
BlockingQueue<jaxbResponse> queue = new LinkedBlockingQueue<>();
RunnableClass runcls = new RunnableClass(queue);
runcls.run()
jaxbResponse response = queue.take(); // waits until takes value from queue
}
}