Interromper thread

6 respostas
heliob

Olá, estou com dúvida de como interromper uma Thread.

tenho esse método num form:

public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		
		Object botao = e.getSource();
		
		if( botao == btnExecutar ){			
			if( btnExecutar.getText() == "Executar" ){
				btnExecutar.setText("Parar");
				tredinha.start();				
			}else if( btnExecutar.getText() == "Parar" ){
				btnExecutar.setText("Executar");
				tredinha.interrupt();				
			}		
		}
		
	}

O run desta thread apenas muda o Text de um label deste form de forma alatória( basicamente um for infinito).

Porém não está interrompendo o processo da Thread.

Cheguei até colocar o script que está dentro do método run(), dentro do escopo de um if ao qual a condição é verificação da interrupção.

public void run(){		
		if( !isInterrupted() ){		
			//codigo que muda texto do Text do label....
		}		
}

Mas mesmo assim não vai...
Alguém tem alguma idéia?

6 Respostas

pedroroxd

Posta o código do tredinha.interrupt();
Provavelmente o problema está lá.

ViniGodoy

Não existe como interromper a execução de uma thread no meio.

Se você precisa fazer isso, terá que definir o valor de uma variável, e testar o tempo todo se esse valor mudou, para então desviar seu código para fora do run.

E

thread.interrupt envia uma exceção InterruptedException para essa thread, mas ela somente será atendida em alguns pontos de parada. Se for no Windows, por exemplo, em que não é possível interromper uma operação de I/O mandando uma exceção, então provavelmente a exceção nunca irá interromper a thread. (Se a thread tiver um Thread.sleep dentro dela, pode ser até que você consiga fazer com que a exceção seja recebida).

Portanto, o método mais seguro é criar uma variável de instância “volatile” cujo valor deve ser checado periodicamente pela thread que deve ser interrompida.

E

Outra coisa é que o texto deve ser comparado com equals, não “==”.

if( btnExecutar.getText() == "Executar" )

Pode até funcionar (devido a algumas razões técnicas que não cumpre listá-las agora, para não confundir mais sua cabeça), mas não é adequado fazer assim. O correto é:

if( "Executar".equals (btnExecutar.getText()) )
KWill

ViniGodoy:
Não existe como interromper a execução de uma thread no meio.

Se você precisa fazer isso, terá que definir o valor de uma variável, e testar o tempo todo se esse valor mudou, para então desviar seu código para fora do run.


Acho que não é sempre assim. Em algumas circustâncias, o “Thread.interrupt()” até que pode funcionar, mas só em algumas circunstâncias, tipo quando o código da “Thread” está bloqueado num “wait()”, “Thread.join()”, “Thread.sleep()” ou alguma operação de I/O em algum “InterruptibleChannel”. O melhor mesmo deve ser seguir o conselho do ViniGodoy e fazer o controle de interrupção usando variáveis semáforos ou algum outro artifício dentro do código da “Thread”.

Inté.

ViniGodoy

KWill:
Acho que não é sempre assim. Em algumas circustâncias, o “Thread.interrupt()” até que pode funcionar, mas só em algumas circunstâncias, tipo quando o código da “Thread” está bloqueado num “wait()”, “Thread.join()”, “Thread.sleep()” ou alguma operação de I/O em algum “InterruptibleChannel”. O melhor mesmo deve ser seguir o conselho do ViniGodoy e fazer o controle de interrupção usando variáveis semáforos ou algum outro artifício dentro do código da “Thread”.
Inté.

É sempre assim, sim.

O Thread.interrupt() só irá fazer com que alguns métodos disparem uma interrupted exception, caso sejam devidamente programados para isso (como é o caso do wait e sleep, que você citou). Além disso, ele faz com que o método Thread.isInterrupted() retorne false.
Só isso.

Ele não interrompe a thread, embora a exception, se tratada corretamente, possa ser usada para desviar o código para fora do run().

O único método que efetivamente matava uma thread era o método stop(). Entretanto, ele pode gerar resource leak, por isso, foi deprecated. Um exemplo é caso a thread abra um arquivo ou adquira um lock. Matar a thread sumariamente não fará com que esse recurso seja liberado.

Portanto, a única maneira segura de se fazer isso é a que eu citei. Teste periodicamente o valor de uma variável (como a Thread.isInterrupt()) e trate corretamente a interrupted exception.

Criado 15 de setembro de 2009
Ultima resposta 16 de set. de 2009
Respostas 6
Participantes 5