Concurrence – interrompre un avenir sans l’annuler

Est-il possible d’interrompre un avenir sans l’annuler?

API java doc:

boolean cancel (boolean mayInterruptIfRunning)

Tente d’annuler l’exécution de cette tâche. Cette tentative échouera si la tâche est déjà terminée, a déjà été annulée ou ne peut pas être annulée pour une autre raison. En cas de succès et si cette tâche n’a pas démarré lorsque l’annulation est appelée, cette tâche ne doit jamais être exécutée. Si la tâche a déjà démarré, le paramètre mayInterruptIfRunning détermine si le thread qui l’exécute doit être interrompu pour tenter de l’arrêter.

Pour capturer l’interruption, nous devons attraper correctement l’exception interrompue ou vérifier la méthode isInterrupted () dans la méthode Runnable / Callable.

Mais il n’y a aucun moyen d’interrompre un avenir en cours à l’aide de l’interface future

Puisque tous les threads sont dans le pool du service d’exécution, personne ne peut faire thread.interrupt (). Est-ce la raison pour laquelle on a supposé que toute interruption ne surviendrait que lorsqu’un futur est annulé ou qu’un pool de threads se termine?

J’essaie de comprendre pourquoi il n’y a pas de méthode d’interruption dans l’interface Future. Toute aide est la bienvenue

La raison en est à cause de la différence entre l’abstraction qui constitue un avenir et l’exécution concrète d’un fil. Nous ne pouvons pas dire si un avenir est lié à un seul thread ou à plusieurs threads. Un futur peut créer de nouveaux fils, de nouveaux futurs, etc.

Considérez ces abstractions comme des interactions entre le code client et l’exécuteur des futures. Sur le plan conceptuel, il est logique de dire “annule cette tâche que je vous ai demandé de faire”, car c’est à vous d’annuler. Je suis peut-être en train de travailler dessus, ou je ne l’ai peut-être pas encore commencé, ou c’est peut-être fini, mais tout va bien, je vais l’annuler si vous le souhaitez. C’est pourquoi nous avons une méthode d’annulation.

Par contre, il n’a pas beaucoup de sens de dire “interrompre votre tâche”. En raison du découplage entre le résultat de l’action (le futur) et le modèle d’exécution (disons un exécuteur), le client n’a pas connaissance des actions entresockets pour accomplir la tâche. Comment peut-on alors attendre du client qu’il sache à quel moment une interruption est appropriée, requirejse ou même prise en charge?

Dans tous les cas, vous pouvez utiliser un délai d’attente afin d’interrompre votre attente.

 get(long timeout, TimeUnit unit) 

Il existe des cas d’utilisation utiles pour le faire.

Le problème de l’API future étant qu’elle ne permet pas de détecter que l’exécution s’est arrêtée. isCancelled () et isDone () renverront heureusement la valeur true même si l’exécution de Callable se poursuit.

Il ne s’agit donc vraiment pas du niveau d’abstraction de l’API future à ce stade. Mais c’est l’incapacité d’identifier la fin de la tâche. Autrement dit, il est impossible de faire la différence entre une demande d’ annulation et une action d’ annulation terminée.

Une solution consiste à utiliser un compte à rebours comme dans la question En attente de la fin d’un futur annulé . Ceci signalera à l’appelant en attente que la tâche est réellement terminée et pas seulement signalée pour s’arrêter.