Le Problème
Je suis à cours multiples appels de certains méthode externe via un ExecutorService. Je voudrais être capable d'interrompre ces méthodes, mais malheureusement, ils ne vérifient pas l'interruption indicateur par eux-mêmes. Est il possible que je puisse la force d'une exception soulevée par ces méthodes?
Je suis conscient que de jeter une exception à partir d'un emplacement arbitraire est potentiellement dangereux, dans mon cas précis, je suis prêt à prendre cette chance et prêt à faire face aux conséquences.
Détails
Par "méthode externe", je veux dire une méthode(s) qui viennent de l'extérieur de la bibliothèque, et je ne peux pas modifier son code (bien que je le peux, mais qui fera d'elle un entretien cauchemar à chaque fois qu'une nouvelle version est disponible).
Les externes sont les méthodes de calcul coûteux, pas IO-lié, de sorte qu'ils ne répondent pas aux interruptions standard et je ne peux pas avec force près d'un canal ou d'un socket ou quelque chose. Comme je l'ai mentionné avant, ils ont également ne pas vérifier l'interruption du pavillon.
Le code est conceptuellement quelque chose comme:
// my code
public void myMethod() {
Object o = externalMethod(x);
}
// External code
public class ExternalLibrary {
public Object externalMethod(Object) {
innerMethod1();
innerMethod1();
innerMethod1();
}
private void innerMethod1() {
innerMethod2();
// computationally intensive operations
}
private void innerMethod2() {
// computationally intensive operations
}
}
Ce que j'ai Essayé
Thread.stop()
sera théoriquement faire ce que je veux, mais elle n'est pas seulement obsolète, mais il est également disponible seulement pour les réels fils, alors que je travaille avec exécuteur de tâches (qui peuvent également partager des discussions avec les tâches futures, par exemple lorsque vous travaillez dans un pool de threads). Néanmoins, si pas de meilleure solution est trouvée, je vais convertir mon code à utiliser l'ancienne Threads au lieu et à l'utilisation de cette méthode.
Une autre option, que j'ai essayé c'est pour marquer myMethod()
et des méthodes similaires avec un spécial "Interruptable" annotation et ensuite utiliser AspectJ (dont je suis certes un néophyte) pour la capture de tous les appels de méthode là - quelque chose comme:
@Before("call(* *.*(..)) && withincode(@Interruptable * *.*(..))")
public void checkInterrupt(JoinPoint thisJoinPoint) {
if (Thread.interrupted()) throw new ForcefulInterruption();
}
Mais withincode
n'est pas récursif pour les méthodes appelées par des méthodes d'appariement, si je dois modifier cette annotation dans le code externe.
Enfin, ce qui est similaire à la précédente question de la mienne - mais la différence notable est que maintenant, je fais face à une bibliothèque externe.