Concorrenza Java - Futures e chiamabili
L'oggetto java.util.concurrent.Callable può restituire il risultato calcolato da un thread in contrasto con l'interfaccia eseguibile che può solo eseguire il thread. L'oggetto Callable restituisce l'oggetto Future che fornisce metodi per monitorare lo stato di avanzamento di un'attività eseguita da un thread. L'oggetto Future può essere utilizzato per controllare lo stato di un Callable e quindi recuperare il risultato dal Callable una volta terminato il thread. Fornisce inoltre funzionalità di timeout.
Sintassi
//submit the callable using ThreadExecutor
//and get the result as a Future object
Future<Long> result10 = executor.submit(new FactorialService(10));
//get the result using get method of the Future object
//get method waits till the thread execution and then return the result of the execution.
Long factorial10 = result10.get();
Esempio
Il seguente programma TestThread mostra l'utilizzo di Futures e Callables in un ambiente basato su thread.
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TestThread {
public static void main(final String[] arguments) throws InterruptedException,
ExecutionException {
ExecutorService executor = Executors.newSingleThreadExecutor();
System.out.println("Factorial Service called for 10!");
Future<Long> result10 = executor.submit(new FactorialService(10));
System.out.println("Factorial Service called for 20!");
Future<Long> result20 = executor.submit(new FactorialService(20));
Long factorial10 = result10.get();
System.out.println("10! = " + factorial10);
Long factorial20 = result20.get();
System.out.println("20! = " + factorial20);
executor.shutdown();
}
static class FactorialService implements Callable<Long> {
private int number;
public FactorialService(int number) {
this.number = number;
}
@Override
public Long call() throws Exception {
return factorial();
}
private Long factorial() throws InterruptedException {
long result = 1;
while (number != 0) {
result = number * result;
number--;
Thread.sleep(100);
}
return result;
}
}
}
Questo produrrà il seguente risultato.
Produzione
Factorial Service called for 10!
Factorial Service called for 20!
10! = 3628800
20! = 2432902008176640000