Hello,
J'ai un souci... Je fais un pool de callable, et je dois insérer un timeout.
J'ai déjà posté sur ce sujet, mais le problème n'est plus le même...
J'ai fait un timeout, mais que faire lorsqu'il est passé? Il n'y a pas un moyen de terminer le Callable? il n'existe pas de méthode .interrupt... Il existe bien un .cancel, ce qui génère une exception, mais le thread se termine quand même, ce qui laisse bloqué le completionService qui est de taille fixe
1 2 3
| Executor executor = Executors.newFixedThreadPool(2);
CompletionService<String> completionService =
new ExecutorCompletionService<String>( executor ); |
Comment faire pour tuer ce process???
Imaginons que je lance 3 process, avec des timeout de 100ms (après quoi un cancel est effectué sur le callable en question)
Les deux premiers que je lance prennent disons 500ms chaqun
Le troisième 50ms
Ce que je voudrais, c'est générer un timeout pour les deux premiers et que le troisième s'éxécute...
Si je fais des
result = completionService.take();
Ca joue, des exceptions de Cancellation sont générées, mais le troisième se lance après 1000ms, car les deux premiers se terminent quand-même!
Si je fais des
1 2
|
result = completionService.poll(100, TimeUnit.MILLISECONDS); |
Le troisième n'a pas le temps de se lancer qu'il est interompu, car les trois timeout du poll sont passé lorsque les deux premiers threads sont terminés...
Je suis vraiment bloqué!
P.S.
Ma classe de gestion des timeout:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Allow to set a timeout on a Callable (thread)
*
* @author ...
*
*/
public class Timeout {
/**
* Constructor
*
* @param delay timeout
*/
public Timeout(long delay){
this.delay = delay;
}
private Future<String> source = null;
private long delay = 1;
private final ScheduledExecutorService TIMER = Executors.newSingleThreadScheduledExecutor();
/**
* Start timeout, and cancel thread when too long
*/
public void startTimeout() {
Runnable cancel = new Runnable() {
public void run() {
source.cancel(true);
}
};
TIMER.schedule(cancel, delay, TimeUnit.MILLISECONDS);
}
/**
* Get the source (current thread) when it has been setted
*
* @return source
*/
public synchronized Future<String> getSource() {
while(source == null){
try {
wait();
} catch (InterruptedException e) {}
}
return source;
}
/**
* Set the source (current thread) and notify
*
* @param source Source (current thread)
*/
public synchronized void setSource(Future<String> source) {
notify();
this.source = source;
}
} |
Et la façon dont je l'utilise:
1 2 3 4
| Future<String> resultTemp = null;
Timeout timeout = new Timeout(100);
resultTemp = completionService.submit( new Th2(text+" 2.1", timeout) );
timeout.setSource(resultTemp); |
Merci d'avance!
A+
Partager