Finalizar threads

8 respostas
R

Pessoal,

Estou jogando um JPanel dentro de um JDialog e nesse JPanel eu tenho threads continuas, do tipo:
run() {
while (true) {
...
}
}
Quando o JDialog for fechado quero finalizar as threads. Ja implementei WindowListener e coloquei o seguinte:
public void windowClosing(WindowEvent e) {
        if (!thread.interrupted()) thread.interrupt();
        System.out.println(thread.interrupted());
    }
    
    public void windowClosed(WindowEvent e) {
        if (!thread.interrupted()) thread.interrupt();
        System.out.println(thread.interrupted());
    }
Sim, eu coloquei tanto em windowClosing quanto em windowClosed, sei que eh redundancia, mas mesmo assim nao tive sucesso... o println nem eh exibido no console e o programa trava porque as threads nao liberaram os recursos. Esse segundo codigo se encontra no JPanel, nao no JDialog. E as threads sao iniciadas no JPanel, tambem.

O que estou fazendo de errado?

Obrigado.

8 Respostas

D

Cara, tive um problema desses também.

Faz o seguinte, cria a thread num evento e ao inves de dar thread.interrupt, mata ela! :twisted: pra ter certeza que ela vai liberar os recursos.

Quando o evento que criou acontecer, ela vai ta la novinha em folha e com recursos sobrando.

Vou procurar meu código aqui e te mostrar.

opa, vou pegar minha carona pra casa e sair do trabalho, quando chegar em casa eu procuro

R

Como assim, “matar” a thread? Usando o stop()?
Andei lendo sobre “encapsulamento” de threads há um tempo e, se não me engano, elas são independentes. Uma thread dentro da outra não manda na outra, por exemplo. Então acho que não captei o que você quis dizer…

Se puder postar o código eu ficaria grato!

Valeu pela resposta!

D

Pow cara, perdi o eclipse, só tenho o meu jar e não to conseguindo ver o código do .class

Me manda seu e-mail por mp que eu te mando meu programa, vc tenta abrir ele e ver onde tá.

Eu juro que se eu achar a maneira ou me lembrar dela eu posto aqui.

Mas pelo que eu me lembre, eu tinha um botão que startaca uma thread com loop infinito se ela estivesse 'morta' e matava se ela estivesse 'viva' (alternava).

Pra isso ele checava se ela existiae se não existia ele criava ela. Se existia ele dava um "Thread.stop" e depois um "Thread = null".

Com isso eu conseguia manter a gui separada do mei loop e interrompia ele com a ação do botão.

Vou continuar procurando o código!

Achei mais ou menos, uma versão antiga que não funcionava, vou tentar alterar ela:

sleepButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
								
				
				if (gui.getSleep()==true){
					sleepButton.setText("Sleep");
					gui.setSleep(false);
					status.setText(" running ");
					status.setBackground(Color.GREEN); //status label shows running
					 
          final Thread thread=new Thread(loop);
						thread.start(); //Starts the ROBOT
					}
					else {
						sleepButton.setText("Run");
						gui.setSleep(true);
						status.setText(" sleeping ");
						status.setBackground(Color.RED); //status label shows sleeping
						thread.stop;
		                                thread=null;
					}
						}
		});  //will change the program's state running<->sleeping

Tipo cara, não tenho certeza da sintaxe, faz tempo, mas a idéia é essa.

"Cria e parte" toda hora e "para e mata" também.

É assim que eu fiz e nunca deu pau.

V

Você não deve em hipótese nenhuma usar o método stop() da classe Thread. Não é a toa que ele está deprecated.

Seu problema é que seu código não tem nenhum tipo de verificação que faça com que a thread pare. O interrupt não “mata” a thread. Ele só pede para a thread parar. Quem faz a programação de como ela deve parar é você.

Ao invés de simplesmente:

while (true) { ... }

Faça:

try { while (!Thread.interrupted()) { ... } } catch (InterruptedException e) { } finally { //Código de finalização aqui, se necessário. }

Isso faz com que a thread finalize gentilmente caso um interrupt() seja recebido. Se a thead estiver num wait, o try catch irá finaliza-la, já que ele também a retirará do while (aliás, é para isso que serve a tal da interrupted exception). Se ela não estiver, a propriedade Thread.interrupted() retornará true, assim que o interrupt for enviado.

Em ambos os casos, você um código de finalização ainda deve rodar do finally, assim você pode fechar arquivos, parar conexões socket, etc.

O método stop() foi tornado deprecated porque:

  1. Gera memory leaks;
  2. Causa instabilidades no sistema;
  3. Pode gerar catástrofes maiores.

Não utilize.

D

O método stop() foi tornado deprecated porque:

  1. Gera memory leaks;
  2. Causa instabilidades no sistema;
  3. Pode gerar catástrofes maiores.

Não utilize.

uhaehuaeuhaeuheauhaeuheha

ainda bem que eu abandonei meu aplicativo…

Acho melhor vc ouvir o ViniGodoy cara, não eu :lol:

V
  1. E nem sempre funciona corretamente. *

Se a thread estiver em um método nativo, Thread.stop não funciona.
É possível dar um catch (ThreadDeath e) ou catch (Throwable e) e a thread acaba não morrendo.

R

Descobri o que estou fazendo de errado: eu atribuo os listeners window a um objeto que nao os suporta, no caso, o JPanel. O que ocorre eh que os eventos de window nem sao chamados porque o JPanel nunca foi “closed” e nunca esteve “closing”; ele apenas nao esta mais visivel.

Segue o codigo que uso (nota: removi coisas desnecessarias e renomeei os objetos pra dar mais clareza):

JDialog jdialog = new JDialog();
JPBlabla jpanel = new JPBlabla(); // instancia da classe que contem o JPanel           
jdialog.add(jpanel);
jdialog.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
jdialog.setVisible(true);

Eu deveria implementar a interface WindowListener no JDialog que eu chamo, certo? Mas como fazer isso se o JDialog nao existe, sendo criado em tempo de execucao, ao contrario do JPanel, que sao classes?

Valeu!

S

estranho… tento usar o

try {

while (!Thread.interrupted()) {

…

}

} catch (InterruptedException e) {

}

finally {

//Código de finalização aqui, se necessário.

}

e ele retorna:

exception java.lang.InterruptedException is never thrown in body of corresponding try statement

Obs: não manjo muito de threads… to tentando aqui na raça

Criado 24 de setembro de 2008
Ultima resposta 30 de set. de 2008
Respostas 8
Participantes 5