30 Stimmen

Wie kann ich externe Methoden unterbrechbar machen?

Das Problem

Ich führe mehrere Aufrufe einer externen Methode über eine ExecutorService . Ich würde diese Methoden gerne unterbrechen, aber leider prüfen sie das Unterbrechungsflag nicht von selbst. Kann ich irgendwie erzwingen, dass eine Ausnahme von diesen Methoden ausgelöst wird?

Ich bin mir bewusst, dass das Auslösen einer Ausnahme von einem beliebigen Ort ist potenziell gefährlich In meinem speziellen Fall bin ich bereit, dieses Risiko einzugehen und die Konsequenzen zu tragen.

Einzelheiten

Mit "externer Methode" meine ich einige Methode(n), die aus einer externen Bibliothek stammen und deren Code ich nicht ändern kann (nun, ich kann, aber das macht es zu einem Wartungsalptraum, wenn eine neue Version veröffentlicht wird).

Die externen Methoden sind rechenintensiv und nicht IO-gebunden, so dass sie nicht auf reguläre Interrupts reagieren und ich kann nicht zwangsweise einen Kanal oder einen Socket oder so schließen. Wie ich bereits erwähnt habe, überprüfen sie auch nicht das Interrupt-Flag.

Der Code sieht in etwa so aus:

// 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
    }
}

Was ich ausprobiert habe

Thread.stop() tut theoretisch das, was ich will, aber es ist nicht nur veraltet, sondern auch nur für tatsächliche Threads verfügbar, während ich mit Executor-Tasks arbeite (die auch Threads mit zukünftigen Tasks teilen können, z. B. wenn sie in einem Threadpool arbeiten). Wenn keine bessere Lösung gefunden wird, werde ich meinen Code jedoch so umstellen, dass er stattdessen altmodische Threads verwendet und diese Methode einsetzt.

Eine andere Möglichkeit, die ich ausprobiert habe, ist die Markierung myMethod() und ähnliche Methoden mit einer speziellen "Interruptable"-Annotation versehen und dann AspectJ (in dem ich zugegebenermaßen ein Neuling bin) verwenden, um dort alle Methodenaufrufe abzufangen - etwa so:

@Before("call(* *.*(..)) && withincode(@Interruptable * *.*(..))")
public void checkInterrupt(JoinPoint thisJoinPoint) {
    if (Thread.interrupted()) throw new ForcefulInterruption();
}

Aber withincode ist nicht rekursiv zu Methoden, die von den passenden Methoden aufgerufen werden, so dass ich diese Anmerkung im externen Code bearbeiten müsste.

Schließlich ist dies vergleichbar mit eine frühere Frage von mir - Ein bemerkenswerter Unterschied ist jedoch, dass ich es jetzt mit einer externen Bibliothek zu tun habe.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X