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

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_(), возможно ли это?

4b9b3361

Ответ 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
        }
    }