venerdì 20 gennaio 2012

Banale esempio di utilizzo dell'interfaccia Future

Esempio future

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.

Esempio

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();
  }
 }
 
 
}
 

Nessun commento:

Posta un commento