May12
May12

Reputation: 2520

How to return a value from a lambda expression?

I have a collection (concurrentHashMap) and a method which should work in a separate thread and return numOfApples:

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

Is it possible to pass num of apples from lambda expression (concurrentHashMap.get(treeNum).getApples()) to the numOfApples variable?

Upvotes: 8

Views: 8080

Answers (1)

Tunaki
Tunaki

Reputation: 137114

The problem is not about returning the value from a lambda expression. It is about returning a result from an asynchronous task.

You won't be able to do that easily using a Runnable. You should use a Callable instead, quoting its Javadoc:

A task that returns a result and may throw an exception.

Also, you definitely should not be creating unmanaged raw threads like that: new Thread(task).start();. You should use an ExecutorService and submit the Callable to it.

Consider the following code:

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

It creates a Callable<Integer> holding the task returning the number of apples. This task is submitted to an ExecutorService (I simply used a cached thread pool here, you might want another). The result is contained inside a Future<Integer> instance, whose get() method will block, wait for the result and then return it.

Upvotes: 6

Related Questions