Dans ce TP, nous allons reprendre les classes du TP précédent
et les réaliser en utilisant différents classes implémentant l'interface
ExecutorService
.
Dans cet exercice, on utilise l'API Request.java (et Answer.java) vue au TP précédent.
Écrire la classe CheapestPooled
en utilisant un ExecutorService
. Pour simplifier le code, on suppose que l'API des requêtes ne lève aucune exception.
Pour rappel, la méthode retrieve()
lance un nombre fixé de threads qui tentent d'obtenir le prix d'un item et un autre thread s'ocuppe de calculer le moins cher, s'il existe.
Vous pouvez utiliser executorService.invokeAll(Collection<? extends Callable<T>> tasks)
.
CheapestPooledWithGlobalTimeout
qui, en plus des paramètres de CheapestPooled
, prend un paramètre timeoutMilliGlobal
. Donc, à la construction, cette classe prend :
item
le nom de l'objet demandé,poolSize
la taille du pool de worker-threads,timeoutMilliPerRequest
le timeout en milli-secondes pour chaque Request
,timeoutMilliGlobal
le timeout en milli-secondes pour l'appel à retrieve
.Request
sont toujours exécutées avec le timeout
timeoutMilliPerRequest
, mais votre code devra en plus garantir
que l'exécution de retrieve
ne prend pas plus
de timeoutMilliGlobal
millisecondes. La réponse renvoyée par retrieve
renverra le prix le moins élevé parmi les réponses obtenues.
CheapestPooledWithGlobalTimeout
en utilisant un ExecutorService
.
Pour rappel, la méthode retrieve()
lance un nombre fixé de threads qui tentent d'obtenir le prix d'un item et un autre thread s'ocuppe de calculer le moins cher, s'il existe.
Votre code doit garantir que l'exécution de retrieve
ne prend pas plus de timeoutMilliGlobal
millisecondes.
Vous pouvez utiliser executorService.invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
. Cette méthode bloque au plus timeout
et annule les tâches qui ne sont pas terminées à ce moment.
En utilisant un ExecutorService
, écrire une classe FastestPooled
dont la méthode retrieve()
lance un nombre fixé de threads qui tentent d'obtenir le prix d'un item et renvoie le premier prix obtenu, s'il existe.
Vous pouvez utiliser T executorService.invokeAny(Collection<? extends Callable<T>> tasks)
.
Dans cet exercice, on considère RequestWithCancel.java une variante de l'API Request
qui diffère de celle-ci par le fait la méthode request
ne prend plus de timeout
. La méthode request
peut donc bloquer
indéfiniment. RequestWithCancel
offre une méthode cancel
permettant d'interrompre la requête depuis un autre thread. Bien entendu, RequestWithCancel
est thread safe. Par exemple :
RequestWithCancel request = new RequestWithCancel("amazon.fr", "pikachu"); new Thread(() -> { try { System.out.println(request.request()); } catch (InterruptedException e) { throw new AssertionError(e); }}).start(); Thread.sleep(5_000); request.cancel();
En utilisant un ExecutorService
, écrire la classe CheapestPooledCancel
qui fait la même chose que CheapestPooled
mais en utilisant des requêtes qui n'ont pas de timeout.
Vous pouvez utiliser un ScheduledExecutorService
pour annuler vos RequestWithCancel
.