Pergunta

Como você matar um java.lang.Thread em Java?

Foi útil?

Solução

Veja rosca este pela Sun sobre o porquê eles obsoleto Thread.stop() . Ele entra em detalhes sobre por que isso era um método ruim e que deve ser feito para parar com segurança threads em geral.

A forma como eles recomendam é usar uma variável compartilhada como uma bandeira que pede a discussão de fundo para parar. Esta variável pode então ser definido por um objecto diferente solicitando o fio terminar.

Outras dicas

Geralmente você não ..

Você pedir para interromper o que quer que está fazendo usando Thread.interrupt () (link javadoc)

Uma boa explicação de por que está no javadoc aqui (java technote link)

threads em java não são mortas, mas a paragem de um fio é feito de uma forma cooperativa . O fio é convidado a terminar e o fio pode, então, desligar graciosamente.

Muitas vezes, um campo volatile boolean é utilizado o que o fio verifica periodicamente e termina quando ela é definida como o valor correspondente.

I não iria usar um boolean para verificar se o segmento deve terminar . Se você usar volatile como um modificador de campo, isso vai funcionar confiável, mas se o seu código se torna mais complexa, pois em vez usa outros métodos de bloqueio dentro do loop while, pode acontecer, que o seu código irá não terminar em todos ou pelo menos leva mais tempo como você pode querer.

Certos métodos de biblioteca bloqueio apoiar interrupção.

Cada segmento já tem um sinalizador booleano estado interrompido e você deve fazer uso dele. Ele pode ser implementado como esta:

public void run() {
   try {
      while (!interrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }
}

public void cancel() { interrupt(); }

O código-fonte adaptado de Java Concurrency in Practice . Como o método cancel() é público você pode deixar outro segmento invocar esse método como você queria.

Uma maneira é através da criação de uma variável de classe e usá-lo como uma sentinela.

Class Outer {
    public static volatile flag = true;

    Outer() {
        new Test().start();
    }
    class Test extends Thread {

        public void run() {
            while (Outer.flag) {
                //do stuff here
            }
        }
    }

}

definir uma variável de classe externa, isto é, a bandeira = verdadeiro no exemplo acima. Defini-lo como falso para 'matar' o fio.

Há uma maneira como você pode fazê-lo. Mas se você tivesse que usá-lo, ou você é um programador ruim ou você está usando um código escrito por programadores ruins. Assim, você deve pensar em parar de ser um programador ruim ou parar usando este código ruim. Esta solução é apenas para situações quando não há outra maneira.

Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );

Eu quero adicionar várias observações, com base nos comentários que se acumularam.

  1. Thread.stop () vai parar um fio se o gerente de segurança permite-o.
  2. Thread.stop () é perigoso. Dito isto, se você estiver trabalhando em um ambiente JEE e você não tem controle sobre o código que está sendo chamado, pode ser necessário.
  3. Você nunca deve parar parar um segmento de trabalho recipiente. Se você deseja executar o código que tende a travar, (com cuidado) iniciar um novo tópico daemon e monitorá-lo, matando, se necessário.
  4. stop () cria um novo erro ThreadDeath no chamando fio e, em seguida, faz com que esse erro a ser aplicada ao destino fio. Portanto, o rastreamento de pilha é geralmente inútil.
  5. Em JRE 6, stop () verifica com o gerente de segurança e em seguida, chama stop1 () que chama stop0 (). stop0 () é código nativo.

Eu votaria para Thread.stop().

Como por exemplo você tem uma operação de longa duração (como uma solicitação de rede). Supostamente você está esperando por uma resposta, mas pode levar algum tempo e que o usuário navegou para outra UI. Esta discussão de espera é agora a) inúteis b) problema potencial, porque quando ele vai ter resultado, é completamente inútil e ele irá desencadear retornos de chamada que podem levar ao número de erros.

Tudo isso e ele pode fazer o processamento de resposta que poderia ser CPU intensa. E você, como um desenvolvedor, pode nem mesmo pará-lo, porque você não pode jogar linhas if (Thread.currentThread().isInterrupted()) em todo o código.

Assim, a incapacidade de força parar um fio estranho.

A questão é bastante vago. Se você quis dizer “como faço para escrever um programa para que um fio pára de funcionar quando eu quero que ele”, em seguida, várias outras respostas devem ser útil. Mas se você quis dizer “Eu tenho uma emergência com um servidor não pode reiniciar agora e eu só preciso de um segmento específico de morrer, aconteça o que acontecer”, então você precisa de uma ferramenta de intervenção para combinar ferramentas de monitoramento como jstack.

Para isso eu criei jkillthread . Veja as instruções para o uso.

Há, evidentemente, o caso em que você estiver executando algum tipo de código não-completamente confiável. (Pessoalmente, tenho isso, permitindo roteiros enviados para executar no meu ambiente Java. Sim, há segurança alarme tocando em todos os lugares, mas é parte da aplicação.) Neste caso infeliz que você em primeiro lugar estão apenas sendo esperançoso, pedindo roteiristas a respeitar algum tipo de sinal run / NÃO FAZEM-run boolean. Sua única decente fail safe é chamar o método stop no segmento se, por exemplo, corre mais do que alguns timeout.

Mas, este é apenas "decente", e não absoluta, porque o código poderia capturar o erro ThreadDeath (ou qualquer exceção que você explicitamente jogar), e não relançar-lo como um fio cavalheiresca é suposto fazer. Assim, a linha inferior é Afaia não há absoluta prova de falhas.

Não há nenhuma maneira de graciosamente matar um fio.

Você pode tentar interromper o fio, uma estratégia comuns é usar uma pílula de veneno à mensagem do thread para parar-se

public class CancelSupport {
    public static class CommandExecutor implements Runnable {
            private BlockingQueue<String> queue;
            public static final String POISON_PILL  = “stopnow”;
            public CommandExecutor(BlockingQueue<String> queue) {
                    this.queue=queue;
            }
            @Override
            public void run() {
                    boolean stop=false;
                    while(!stop) {
                            try {
                                    String command=queue.take();
                                    if(POISON_PILL.equals(command)) {
                                            stop=true;
                                    } else {
                                            // do command
                                            System.out.println(command);
                                    }
                            } catch (InterruptedException e) {
                                    stop=true;
                            }
                    }
                    System.out.println(“Stopping execution”);
            }

    }

}

BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);

http://anandsekar.github.io/cancel-support-for-threads /

Geralmente você não matar, parar ou interromper um thread (ou verificar wheter é interrompida ()), mas deixá-lo terminar naturalmente.

É simples. É possível utilizar qualquer conjunto loop com (volátil) booleano variável método dentro de execução () a actividade da linha de controlo. Você também pode retornar a partir de fios ativo para o segmento principal para pará-lo.

Desta forma, você graciosamente matar uma thread :).

As tentativas de rescisão fio abrupta são bem conhecidos má prática de programação e evidência de design do aplicativo pobres. Todos os tópicos na aplicação multithreaded explícita e implicitamente compartilham o mesmo estado do processo e forçado a cooperar uns com os outros para mantê-lo consistente, caso contrário, sua aplicação vai ser propenso aos erros que será muito difícil de diagnosticar. Então, é uma responsabilidade do desenvolvedor para fornecer uma garantia de tal consistência através de um projeto cuidadoso e clara aplicação.

Existem duas principais soluções certas para as terminações de fios controlados:

  • O uso da bandeira volátil compartilhada
  • A utilização do par de Thread.interrupt () e Thread.interrupted () métodos.

Bem e explicação detalhada dos problemas relacionados com a rescisão tópicos abruptas, bem como exemplos de soluções erradas e certas para o término tópicos controlada pode ser encontrada aqui:

https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads

Aqui estão um par de boas leituras sobre o assunto:

O que você faz com InterruptedException?

fechando tópicos limpa

'Matar um fio' não é a frase certa para usar. Aqui está uma maneira podemos implementar graciosa conclusão / saída da linha na vontade:

Runnable que eu usei:

class TaskThread implements Runnable {

    boolean shouldStop;

    public TaskThread(boolean shouldStop) {
        this.shouldStop = shouldStop;
    }

    @Override
    public void run() {

        System.out.println("Thread has started");

        while (!shouldStop) {
            // do something
        }

        System.out.println("Thread has ended");

    }

    public void stop() {
        shouldStop = true;
    }

}

A classe de disparo:

public class ThreadStop {

    public static void main(String[] args) {

        System.out.println("Start");

        // Start the thread
        TaskThread task = new TaskThread(false);
        Thread t = new Thread(task);
        t.start();

        // Stop the thread
        task.stop();

        System.out.println("End");

    }

}

Eu não recebi a interrupção ao trabalho no Android, então eu usei este método, funciona perfeitamente:

boolean shouldCheckUpdates = true;

private void startupCheckForUpdatesEveryFewSeconds() {
    Thread t = new Thread(new CheckUpdates());
    t.start();
}

private class CheckUpdates implements Runnable{
    public void run() {
        while (shouldCheckUpdates){
            //Thread sleep 3 seconds
            System.out.println("Do your thing here");
        }
    }
}

 public void stop(){
        shouldCheckUpdates = false;
 }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top