2015-12-17 12 views
6

Ho una collezione (concurrentHashMap) e un metodo che dovrebbe funzionare in un thread separato e tornare numOfApples:Come restituire un valore da un'espressione lambda?

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

E 'possibile passare num di mele da un'espressione lambda (concurrentHashMap.get(treeNum).getApples()) alla variabile numOfApples?

risposta

4

Il problema non consiste nel restituire il valore da un'espressione lambda. Si tratta di restituire un risultato da un'attività asincrona.

Non sarà possibile farlo facilmente utilizzando Runnable. È necessario utilizzare un Callable, citando il Javadoc:

Un'attività che restituisce un risultato e può generare un'eccezione.

Inoltre, 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.

Si consideri il seguente codice:

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

Si crea una Callable<Integer> tenendo il compito di restituire il numero di mele. Questa attività è sottoposta a un ExecutorService (ho semplicemente usato un pool di thread in cache qui, potresti volerne un altro). Il risultato è contenuto in un'istanza Future<Integer>, il cui metodo get() verrà bloccato, attendere il risultato e quindi restituirlo.

+2

Ma se l'OP insiste su questo, è possibile creare un ['FutureTask'] (http://docs.oracle.com/javase/8/docs/api/?java/util/concurrent/FutureTask.html) a mano, passalo a un nuovo thread creato manualmente, avvialo e chiama 'get' in seguito. Il principio è lo stesso della tua risposta. – Holger

+0

Tunaki, come controllare che il metodo venga eseguito in un thread separato? – May12

+0

Per verificare che il metodo venga eseguito in un thread separato, si potrebbe fare qualcosa come 'System.out.println (" Thread: "+ Thread.currentThread(). GetId());' nel metodo 'getApples()' e nel 'Callable'. I valori ID non saranno uguali. –

Problemi correlati