60

run方法Runnable有返回类型void,不能返回值。但是,我想知道是否有任何解决方法。

我有这样的方法:

public class Endpoint {
    public method() {
       Runnable runcls = new RunnableClass();
       runcls.run()
    }
}

方法run是这样的:

public class RunnableClass implements Runnable {
    
    public JaxbResponse response;

    public void run() {
        int id = inputProxy.input(chain);
        response = outputProxy.input();
    }
}

我想response访问method. 这可能吗?

4

8 回答 8

77

使用Callable<V>而不是使用Runnable接口。

例子:

public static void main(String args[]) throws Exception {
    ExecutorService pool = Executors.newFixedThreadPool(3);
    Set<Future<Integer>> set = new HashSet<>();

    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接口的类。

于 2012-12-03T13:42:56.800 回答
16
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
    }
}
于 2012-12-03T13:47:48.580 回答
7

看看Callable类。这通常通过executor 服务提交

它可以返回一个future对象,该对象在线程完成时返回

于 2012-12-03T13:42:38.080 回答
5

是的,有解决方法。只需使用队列并将您想要返回的值放入其中。并从另一个线程中获取这个值。

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
        }
    }
于 2017-11-04T06:35:20.187 回答
3

如果您添加一个字段,RunnableClass您可以将其设置run并读取method_。但是,Runnable它是一个糟糕的(Java 关键字)interface,因为它没有告诉您有关(概念)接口的任何信息(API 文档中唯一有用的一行:“该方法的一般约定run是它可以采取任何行动。”)。使用更有意义的界面(可能会返回一些东西)要好得多。

于 2012-12-03T13:46:03.910 回答
3

一种方法是,我们必须使用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来保存线程中的值。

于 2014-10-08T14:38:28.220 回答
1

尝试以下

public abstract class ReturnRunnable<T> implements Runnable {

    public abstract T runForResult();

    @Override
    public void run() {
        runForResult();
    }
}
于 2018-09-05T17:42:39.707 回答
0

看看callable interface,也许这适合您的需求。您还可以尝试通过在方法中调用 setter-method 来获取响应字段的run()

public void run() {
    int id;
    id =inputProxy.input(chain);
    response = outputProxy.input();
    OuterClass.setResponseData(response);

}
于 2012-12-03T13:43:58.453 回答