Melhor maneira de identificar e descartar o fio bloqueado em java
-
28-09-2019 - |
Pergunta
Eu tenho que chamar um módulo de terceiros da função em um novo thread. Pelo que vi, a chamada completa rapidamente se tudo correu bem ou apenas pendura para sempre trancar o tópico. O que é uma boa maneira de iniciar o tópico e fazer a chamada e aguardar alguns segundos e, se o thread ainda estiver vivo, assumindo que ele está trancado, mate (ou pare ou abandone) o thread sem usar métodos depreciada.
Eu tenho algo assim por enquanto, mas não tenho certeza se essa é a melhor maneira de fazê -lo e quero evitar ligar para o thread.stop (), pois está preso. Obrigado.
private void foo() throws Exception
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
// stuff that could potentially lock up the thread.
}
};
Thread thread;
thread = new Thread(runnable);
thread.start();
thread.join(3500);
if (thread.isAlive())
{
thread.stop();
throw new Exception();
}
}
Solução
public void stop() {
if (thread != null) {
thread.interrupt();
}
}
Veja este link Em como parar um tópico, ele cobre bem o assunto
Outras dicas
Não há como fazer o que você deseja (incondicionalmente). Por exemplo, se o stuff that could potentially lock up the thread.
Parece que isso, não há como detê -lo, sempre aquém do System.Exit ():
public void badStuff() {
while (true) {
try {
wait();
}
catch (InterruptedException irex) {
}
}
}
Quando o seu aplicativo ficar preso, execute o jstack (ou use o depurador). Tente descobrir o que mantém a função e conserte -a.
Eu olharia para o java.util.concurrent
Executor
estrutura e especificamente o Future<T>
interface. Com isso, você é um pouco abstraído dos caprichos de java.lang.thread e obtém um bom dissociação de quais são as tarefas de como elas são executadas (seja em um fio separado, se o fio vem de um pool ou é instanciado no voar, etc.)
Uma instância futura, pelo menos, te dá isDone
e isCancelled
métodos.
o ExecutorService
(subinterface de Executor
) fornece alguns meios de desligar quaisquer tarefas de excesso. Ou confira o ExecutorService.awaitTermination(long timeout, TimeUnit unit)
método
private void foo() throws Exception
{
ExecutorService es = Executors.newFixedThreadPool(1);
Runnable runnable = new Runnable()
{
@Override
public void run()
{
// stuff that could potentially lock up the thread.
}
};
Future result = es.submit(runnable);
es.awaitTermination(30, TimeUnit.SECONDS);
if (!result.isDone()){
es.shutdownNow();
}
}