NANOSECONDS
;
MICROSECONDS
;
MILLISECONDS
;
SECONDS
;
MINUTES
;
HOURS
;
DAYS
.
Runnable
. Elle fonctionne comme celle-ci, sauf que la méthode
run()
qu'elle définit retourne une valeur générique, de type
V
, et peut jeter une exception.
Future
modélise des tâches qui s'exécutent dans un autre
thread
que le
thread
courant. Cette interface ne définit pas comment on peut lancer l'exécution de cette tâche. En revanche, elle définit comment récupérer le résultat de cette tâche, par la méthode
get()
, qui existe en deux versions.
get()
: retourne le résultat de la tâche. L'appel à cette méthode ne retourne de résultat que lorsque le calcul est terminé. On dit que cet appel est bloquant.
get(long timeout, TimeUnit unit)
: retourne le résultat de cette tâche. Si ce résultat n'est toujours pas disponible au bout du temps précisé en paramètre, alors cette méthode jette une exception de type
TimeoutException
.
cancel()
: permet d'interrompre l'exécution de cette tâche ;
isCancelled()
: retourne
true
si cette tâche a été interrompue ;
isDone()
: retourne
true
si l'exécution de cette tâche est terminée, et que son résultat est disponible.
RunnableFuture
est une extension de l'interface
Future
et de l'interface
Runnable
. Elle n'ajoute pas de méthode à ces deux interfaces.
Enfin, l'API Concurrent nous fournit une classe,
FutureTask<V>
, qui implémente ces deux interfaces. On construit une instance de cette classe en lui passant en paramètre une tâche à effectuer, soit sous forme de
Runnable
, soit sous forme de
Callable<V>
. Dans le premier cas, on doit également lui fournir l'objet qui sera retourné par la méthode
get()
, puisque la méthode
run()
de
Runnable
ne retourne rien.
Voyons un exemple de fonctionnement de cette classe sur un exemple simple.
Exemple 82. Utilisation de
FutureTask<V>
public static void main(String... args) { // création d'une instance de FutureTask<String> FutureTask<String> future = new FutureTask<String>( // création d'une instance de Callable, à l'aide // d'une classe anonyme new Callable<String>() { public String call() throws Exception { try { // on simule de façon simple un calcul // qui prend du temps Thread.sleep(2000) ; } catch (InterruptedException e) { // rien } // et l'on retourne le nom du thread // dans lequel on se trouve return Thread.currentThread().getName() ; } } ) ; // un future est une instance de Runnable, on peut // donc le lancer de cette façon new Thread(future).start() ; // on affiche le nom du thread dans lequel on se trouve System.out.println(Thread.currentThread().getName()) ; // jette ExecutionException // puis le résultat de l'exécution de notre tâche System.out.println(future.get()) ; }
main Thread-0On remarquera que le premier message est affiché immédiatement, alors que le second prend un peu plus de temps. On remarquera enfin que notre tâche a bien été exécutée dans un thread différent de celui dans lequel le code de la méthode
main()
l'a été.
Nous verrons dans la suite que l'on peut lancer des tâches de type
Future
de façon plus intelligente que ce que nous avons fait.
Future<V>
.
ScheduledFuture<V>
modélise des tâches prévues pour être exécutées dans le futur, après un certain temps.
RunnableScheduledFuture<V>
permet en plus à cette tâche d'être exécutée à nouveau, de façon périodique.