如何从lambda表达式返回一个值?

May*_*y12 6 java lambda java-8

我有一个collection(concurrentHashMap)和一个方法,它应该在一个单独的线程中工作并返回numOfApples:

public int getApples(String treeNum) {
    int numOfApples = null;
    Runnable task = () -> {concurrentHashMap.get(treeNum).getApples(); };
    new Thread(task).start() ;
    return numOfApples;
}
Run Code Online (Sandbox Code Playgroud)

是否可以将lambda expression(concurrentHashMap.get(treeNum).getApples())中的num个数量传递给numOfApples变量?

Tun*_*aki 6

问题不在于从 lambda 表达式返回值。它是关于从异步任务返回结果。

您将无法使用Runnable. 你应该使用 aCallable来代替,引用它的 Javadoc:

返回结果并可能引发异常的任务。

此外,你绝对不应该创建这样的非托管的原纱:new Thread(task).start();。您应该使用 anExecutorService并将 提交Callable给它

考虑以下代码:

public int getApples(String treeNum) {
    Callable<Integer> task = () -> concurrentHashMap.get(treeNum).getApples();
    Future<Integer> future = Executors.newCachedThreadPool().submit(task);
    return future.get();
}
Run Code Online (Sandbox Code Playgroud)

它创建了一个Callable<Integer>返回苹果数量的持有任务。这个任务被提交给一个ExecutorService(我在这里只是使用了一个缓存的线程池,你可能需要另一个)。结果包含在一个Future<Integer>实例中,其get()方法将阻塞,等待结果然后返回。

  • 但如果 OP 坚持,可以手动创建一个 [`FutureTask`](http://docs.oracle.com/javase/8/docs/api/?java/util/concurrent/FutureTask.html) ,将它传递给一个新的手动创建的线程,启动它,然后调用`get`。原理与您的答案相同。 (2认同)