2015-12-17 11 views
6

Ich habe eine Sammlung (concurrentHashMap) und ein Verfahren, das in einem separaten Thread und das Rück numOfApples funktionieren soll:Wie gibt man einen Wert von einem Lambda-Ausdruck zurück?

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

Ist es möglich, passieren num von Äpfeln aus Lambda-Ausdruck (concurrentHashMap.get(treeNum).getApples()) an die numOfApples Variable?

Antwort

4

Das Problem besteht nicht darin, den Wert von einem Lambda-Ausdruck zurückzugeben. Es geht darum, ein Ergebnis von einer asynchronen Aufgabe zurückzugeben.

Mit einem Runnable können Sie das nicht so einfach tun. Sie sollten stattdessen einen Callable verwenden, der seinen Javadoc zitiert:

Eine Aufgabe, die ein Ergebnis zurückgibt und eine Ausnahme auslösen kann.

Auch 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.

Betrachten Sie den folgenden Code ein:

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

Es schafft eine Callable<Integer> die Aufgabe, die die Zahl der Äpfel zurück. Diese Aufgabe wird an eine ExecutorService gesendet (ich habe hier einfach einen Cache-Thread-Pool verwendet, möglicherweise möchten Sie einen anderen). Das Ergebnis ist in einer Future<Integer> Instanz enthalten, deren get()-Methode blockiert, auf das Ergebnis wartet und es dann zurückgibt.

+2

Aber wenn das OP darauf bestehen, ist es möglich, eine ['FutureTask'] zu erstellen (http://docs.oracle.com/javase/con/docs/api/?java/util/concurrent/FutureTask.html)) Übergeben Sie es manuell an einen neuen manuell erzeugten Thread, starten Sie es und rufen Sie danach 'get' auf. Das Prinzip ist das gleiche wie in Ihrer Antwort. – Holger

+0

Tunaki, wie überprüft man, ob diese Methode in einem separaten Thread ausgeführt wird? – May12

+0

Um zu überprüfen, ob die Methode in einem separaten Thread ausgeführt wird, können Sie etwas wie 'System.out.println (" Thread: "+ Thread.currentThread(). GetId());' in der Methode 'getApples()' tun im 'Callable'. Die ID-Werte sind nicht identisch. –

Verwandte Themen