Banale esempio di utilizzo dell'interfaccia Future a cura di Flavio Casadei Della Chiesa
In questa pagina si vuole descrivere il funzionamento dell'interfaccia 'java.util.concurrent.Future
'.
Le API Java 5 dicono che
un Future rappresenta il risultato di una computazione asincrona
, …,
il risultato può essere recuperato con il metodo get solamente quando la computazione è completata, eventualmente bloccando il chiamante fino a quando il risultato non è pronto
.
In questo esempio si vogliono testare due processori 'p1
' e 'p2
' e si da loro da calcolare un risultato.
Il testa ha successo se entrambi i processori danno lo stesso risultato altrimenti fallisce.
Il calcolo del risultato è piuttosto complesso, si delega quindi ad un esecutore l'esecuzione del calcolo su entrambi i processori e si aspetta che questo abbia finito prima di confrontare i risultati.
'NOTA: l'esempio è assai semplice: non ci sono calcoli complicati, c'è solo un random che può far guastare un processore
'.
package test.esecutore; /** * Usare solo a scopo didattico! */ import java.util.concurrent.Callable; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; import junit.framework.TestCase; public class TestFuture extends TestCase { //valore atteso dal calcolo private static final Double CLEAN = 1.0; //probabilità di successo del primo procesore private static final double okProb1 = 0.6; //probabilità di successo del secondo processore private static final double okProb2 = 0.65; public void testFoo() throws Exception{ //Esecutore dei task Executor executor = new ThreadPerTaskExecutor(); //Future del primo processore FutureTask<Double> proc1 = new FutureTask<Double>(new Callable<Double>() { public Double call() throws InterruptedException { Double retval = CLEAN; double d = Math.random(); if ( d > okProb1) { retval = d; } Thread.sleep( (long)Math.floor(d*500 ) ); return retval; }}); // Future del secondo processore FutureTask<Double> proc2 = new FutureTask<Double>(new Callable<Double>() { public Double call() throws InterruptedException { Double retval = CLEAN; double d = Math.random(); if ( d > okProb2) { retval = d; } Thread.sleep( (long)Math.floor(d*500 ) ); return retval; }}); //eseguo in modo asincrono entrambi i calcoli executor.execute(proc1); executor.execute(proc2); //prendo i risultati Double p1 = proc1.get(); Double p2 = proc2.get(); // li confronto assertEquals(p1, p2); } //Semplice esecutore asincrono. Non usare in produzione!!!!! class ThreadPerTaskExecutor implements Executor { public void execute(Runnable r) { new Thread(r).start(); } } }