J'ai essayé de nombreuses façons d'arrêter immédiatement une tâche qui a démarré en utilisant un ExecutorService, sans succès.Comment arrêter immédiatement une tâche démarrée à l'aide d'un ExecutorService?
Future<Void> future = executorService.submit(new Callable<Void>(
public Void call() {
... do many other things here..
if(Thread.currentThread.isInterrupted()) {
return null;
}
... do many other things here..
if(Thread.currentThread.isInterrupted()) {
return null;
}
}
));
if(flag) { // may be true and directly cancel the task
future.cancel(true);
}
Parfois, je dois annuler la tâche immédiatement après son démarrage, vous pouvez être curieux de savoir pourquoi je veux ce faire, eh bien, vous pouvez imaginer un sénario qu'un utilisateur touche accidentellement le bouton « Télécharger » pour démarrer une "Télécharger tâche" et il veut immédiatement annuler l'action parce que c'était juste un clic accidentel.
Le problème est que après avoir appelé future.cancel (true), la tâche n'est pas arrêté et Thread.currentThread.isInterrupted() retourne encorefaux et je n'ai aucun moyen de savoir la tâche a été arrêté depuis l'intérieur de la méthode call().
Je pense à mettre un drapeau comme annulé = true après avoir appelé la méthode future.cancel (true) et vérifier que le drapeau en permanence dans l'appel(), je pense que c'est un hack et le code pourrait être très laid car l'utilisateur peut démarrer plusieurs tâches en même temps.
Existe-t-il un moyen plus élégant de réaliser ce que je veux?
EDIT:
Ce vraiment me rend fou. J'ai passé presque une journée sur ce problème maintenant. Je vais essayer d'expliquer un peu plus le problème auquel je suis confronté.
Je fais ce qui suit pour commencer 5 tâches, chaque tâche démarrera 5 threads pour télécharger un fichier. et puis j'arrête toutes les 5 tâches immédiatement. Pour tous les appels de méthode ci-dessous, je démarre un thread (ExecutorService.submit (task)) pour le rendre asynchrone comme vous pouvez le voir à partir des suffixes des méthodes.
int t1 = startTaskAysnc(task1);
int t2 = startTaskAysnc(task2);
int t3 = startTaskAysnc(task3);
int t4 = startTaskAysnc(task4);
int t5 = startTaskAysnc(task5);
int stopTaskAysnc(t1);
int stopTaskAysnc(t2);
int stopTaskAysnc(t3);
int stopTaskAysnc(t4);
int stopTaskAysnc(t5);
dans startTaskAysnc(), je lance simplement une connexion socket au serveur distant pour obtenir la taille du fichier (ce qui est certainement va prendre un certain temps), après avoir obtenu avec succès le fileSize, je vais commencer 5 discussions pour télécharger différentes parties du fichier. comme ce qui suit (le code est simplifié pour le rendre plus facile à suivre):
public void startTaskAsync(DownloadTask task) {
Future<Void> future = executorService.submit(new Callable<Void>(
public Void call() {
// this is a synchronous call
int fileSize = getFileSize();
System.out.println(Thread.currentThread.isInterrupted());
....
Future<Void> futures = new Future<Void>[5];
for (int i = 0; i < futures.length; ++i) {
futures[i] = executorService.submit(new Callable<Void>(){...});
}
for (int i = 0; i < futures.length; ++i) {
futures[i].get(); // wait for it to complete
}
}
));
synchronized (mTaskMap) {
mTaskMap.put(task.getId(), future);
}
}
public void stopTaskAysnc(int taskId) {
executorService.execute(new Runnable(){
Future<Void> future = mTaskMap.get(taskId);
future.cancel(true);
});
}
Je remarqué un comportement étrange qui après avoir appelé stopTaskAsync() pour les 5 tâches, il y aurait toujours au moins une tâche got s'est arrêté (c'est-à-dire Thread.currentThread.isInterrupted() renvoie true) et les 4 autres tâches sont en cours d'exécution.
Et j'ai essayé vos suggestions en définissant UncaughtExceptionHandler, mais rien ne sort de cela.
EDIT:
Le problème a été résolu dans ce lien: Can't stop a task which is started using ExecutorService
Salut, @asdasd, j'ai édité ma question, s'il vous plaît donnez-moi de l'aide si vous avez une idée. Merci. – neevek