Parar uma Thread

6 respostas
P

Pessoal, eu abro uma Thread em um classe e depois de certo tempo eu preciso finalizar o seu funcionamento, estou tentando fazer isso da seguinte forma:

if(jRadioButtonDesligar.isEnabled()){
                thread1.interrupt();
            }

Porém quando eu clico no radio para executar o código lança a exceção:

InterruptedException

Alguém sabe me informar como eu para o funcionamento da Thread sem lançar essa exceção?

6 Respostas

ViniGodoy

O ideal é você preparar uma condição em seu runnable, que finalize o método run.

Algo assim:

public void myRunnable implements Runnable {
   private volatile void condicao = false;

   public void run() {
      try {
         while (!condicao) {
            //Processamento de sua thread
         }
      } catch (InterruptedException e) {
         //Loga a exceção
      }
   }
   
   public void parar() {
      condicao = true;
   }
}
Depois, no seu código:
MyRunnable mr = new MyRunnable();
new Thread(mr).start();
//faz outras coisas e, quando quiser parar a thread
mr.parar();

Dá também uma lida nessa explicação:
http://www.guj.com.br/posts/list/52481.java#276136

P

Cara eu até já tinha lido o tópico que vc indicou, fazendo o que vc fez a Thread start normal, mas não finaliza. Olha o código que eu implementei:
Na classe principal faço isso ao clicar em um radiobutton:

leitura = true;
thread1 = new Thread(threadgroup, new Runnable() {
                public void run(){
                    while(leitura == true){                        
                        //Abrindo conexão serial
                        //SerialComLeitura serial = new SerialComLeitura("COM1", 9600, 3000);
                        serial.HabilitarLeitura();
                        serial.ObterIdDaPorta();
                        serial.AbrirPorta();
                        serial.LerDados();
                        for(int i = 1; i > 0; i++){                                              
                            //Rotina para gravação dos dados no banco
                            if(gravar == true){
                                jButtonGravar.setEnabled(true);
                                //Insere automaticamente a pesagem para controle

                            }else{
                                jButtonGravar.setEnabled(false);
                            }

                            peso1 = serial.getPeso1();
                            pesoInt = (int)serial.getPeso1();

                            //Inseri o peso na lista.
                            dados.add(Double.toString(peso1));
                            peso2 = Double.parseDouble(dados.get(i -1).toString());

                            //System.out.println("Cont " + cont);
                            System.out.println("Peso1 " + peso1);
                            System.out.println("Peso2 " + peso2);
                            System.out.println("Cont " + cont);
                            if(pesoInt >= 1 && pesoInt <= 9){
                                if(Math.abs(peso1 - peso2) > TOLERANCE){
                                    //Peso diferente
                                    //System.out.println("Peso diferente");
                                    jTextFieldPeso.setForeground(new java.awt.Color(204, 204, 0));
                                    jTextFieldPeso.setText(Double.toString(peso1));
                                    cont = 0;
                                }else{
                                    //System.out.println("Peso igual");
                                    //Peso igual
                                    jTextFieldPeso.setText(Double.toString(peso1));
                                    cont++;
                                }
                                if(cont > 6){
                                    gravar = true;
                                    jTextFieldPeso.setForeground(new java.awt.Color(0, 153, 51));
                                }
                            }else{
                                //Limpa as variáveis de controle
                                //System.out.println("Peso fora de paramêtros.");
                                gravar = false;
                                cont = 0;
                                jTextFieldPeso.setForeground(new java.awt.Color(255, 0, 0));
                                jTextFieldPeso.setText(Double.toString(peso1));
                                //dados.clear();
                            }
                            try{
                                thread1.sleep(500);
                            }catch(InterruptedException ie){
                                
                            }
                        }
                    }
                }
            }); 
            thread1.start();

E depois quando clico em outro radio eu ponho a variavel leitura para false para finalizar o while do método run, mas não finaliza.

if(leitura == true){ serial.FecharCom(); leitura = false; }
Como só falta isso para entregar o soft to enrolado até agora.

davidbuzatto

Desculpa a pergunta cretina, mas sua variável leitura é a mesma para os dois trechos de código, ou vc está declarando ela de novo?

P

É a mesma. Declaro ela somente uma vez lá em cima e vou utilizando ela por todo o código.

ViniGodoy

A variável leitura está declarada como volatile?

Você tem certeza que sua thread sai em algum momento do método LeDados()? Pode ser necessário usar uma versão não bloqueante do método (tipo, que lê por um tempo máximo).

O que muitas vezes acontece é a thread estar parada no leDados. Nesse caso, a thread ficará esperando indefinidamente, já que esse método também não responde ao interrupt().

Se você trocar por uma versão não bloqueante do método (ou que bloqueie por um curto período de tempo), você poderá continuar verificando a sua variável de controle de tempos em tempos.

Uma coisa é certeza. Você até poderia tentar usar o suspend() e forçar a interrupção da thread. Mas pense nas consequências disso: A porta serial ainda estaria ocupado e isso certamente levaria o sistema a um estado muito feio e inválido. É por isso que não há um comando desses para interromper uma thread.

O que você deve fazer é garantir que seu código teste a condição de vez enquando. E para isso, não pode usar um método que possa bloquear o processamento ou esperar por um recurso para sempre.

P

É vou dar uma olhada aqui para resolver isso.
Valeu pelas dicas.

Criado 8 de junho de 2007
Ultima resposta 8 de jun. de 2007
Respostas 6
Participantes 3