Como posso tornar métodos externos interruptíveis?

O problema

Estou executando várias invocações de algum método externo por meio de umExecutorService. Gostaria de poder interromper esses métodos, mas, infelizmente, eles não verificam o sinalizador de interrupção sozinhos. Existe alguma maneira de forçar uma exceção a ser levantada com esses métodos?

Estou ciente de que lançar uma exceção de um local arbitrário éPotencialmente perigoso, no meu caso específico, estou disposto a aproveitar essa oportunidade e preparado para lidar com as consequências.

Detalhes

Por "método externo", quero dizer alguns métodos que vêm de uma biblioteca externa e não consigo modificar seu código (bem, posso, mas isso o tornará um pesadelo de manutenção sempre que uma nova versão for lançada).

Os métodos externos são computacionalmente caros, não vinculados a IO; portanto, eles não respondem a interrupções regulares e não consigo fechar com força um canal, um soquete ou algo assim. Como mencionei antes, eles também não verificam o sinalizador de interrupção.

O código é conceitualmente algo como:

// 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
    }
}
O que eu tentei

Thread.stop() teoricamente, fará o que eu quero, mas ele não só está obsoleto, mas também está disponível apenas para threads reais, enquanto estou trabalhando com tarefas do executor (que também podem compartilhar threads com tarefas futuras, por exemplo, ao trabalhar em um pool de threads) . No entanto, se nenhuma solução melhor for encontrada, converterei meu código para usar Threads à moda antiga e usar esse método.

Outra opção que tentei é marcarmyMethod() e métodos semelhantes com uma anotação especial "Interrompível" e, em seguida, use o AspectJ (que eu sou um novato) para capturar todas as invocações de métodos lá - algo como:

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

Maswithincode não é recursivo aos métodos chamados pelos métodos correspondentes, então eu precisaria editar esta anotação no código externo.

Finalmente, isso é semelhante aouma pergunta anterior minha - embora uma diferença notável seja que agora estou lidando com uma biblioteca externa.

questionAnswers(8)

yourAnswerToTheQuestion