Concurrence Java - Futures et Callables

L'objet java.util.concurrent.Callable peut renvoyer le résultat calculé effectué par un thread contrairement à l'interface exécutable qui ne peut exécuter que le thread. L'objet Callable renvoie l'objet Future qui fournit des méthodes pour surveiller la progression d'une tâche exécutée par un thread. L'objet futur peut être utilisé pour vérifier l'état d'un appelable, puis récupérer le résultat de l'appelable une fois le thread terminé. Il fournit également une fonctionnalité de temporisation.

Syntaxe

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

Exemple

Le programme TestThread suivant montre l'utilisation de Futures et Callables dans un environnement basé sur les threads.

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

Cela produira le résultat suivant.

Production

Factorial Service called for 10!
Factorial Service called for 20!
10! = 3628800
20! = 2432902008176640000