Duvidas sobre THREAD

13 respostas
E

Boa tarde,

Então tenho uma dúvida sobre thread, queria saber se quando acontece uma exceção dentro do código q a thread está rodando, ela morre ou ela fica parada na memória ou servidor sei la???

como faço pra tratar algum erro que pode dar no processo que a thread esta rodando? pq acredito que não está morrendo quando da alguma exceção… e o sistema com o tempo começa a ficar muito lendo!!

quando não da erro … fica normal… quando da algum erro px: Null pointer exception… parece que ela fica na memória e não morre…

alguem sabe me explicar mais ou menos ai???

vlw

13 Respostas

T

Quando acontece um erro durante a execução do código de uma Thread, é lançanda uma Exception. Se não tratada, a exception vai “descendo” na pilha até que chegue no primeiro executado: o método Main. Para visualizar todo este processo, da uma olhada no stacktrace do erro.

Mas, para nossa sorte, temos o tratamento de erros em java! Onde lá você pode dizer que tipo de erro pode acontecer e o que fazer quando isto acontece.

Estrutura:

try{ // Seu código aqui }catch(Exception e) //Aqui será definido que tipo de exceção será tratada. { e.getMessage(); // Aqui você trata o erro. Neste caso eu apenas exibí o erro. }

  • É possível tratar mais de uma exceção por vez.
  • Não é recomendado generalizar exceções. Vai atrapalhar na melhoria do código posteriormente e no front-end para o cliente saber o que aconteceu.

Mais sobre Threas em “Artigos” aqui no guj: http://www.guj.com.br/article.listByTag.logic?tag=threads

E

Entendi cara vou tratar o erro…

mas isso q vc falou
“Se não tratada, a exception vai “descendo” na pilha até que chegue no primeiro executado: o método Main”

isso pode causar um travamento … deixar o sistema lento… ela chega no man… e morre ou atrapalha o processo??

vlw

E

ah mais uma coisa

pra tratar algum erro q pode ocorrer dentro da thread eu faria assim??

Thread thread = new Thread(threadBuilder);
	try {
		thread.start();
	} catch (Exception e) {
		thread.suspend();
		thread.stop();
		thread.interrupt();
		thread.interrupted();
		thread.destroy();
	}

pq caso acontece alguma exception, tenho q mata-la… sei la fazer alguma coisa… para que o sistema continue normal…

caso seja isso … qual dos métodos eu uso pra tirar a thread da frente

T

Certeza cara? Me corrija se eu estiver errado… mas pelo o que eu entendi la na caelum a exceção irá buscar tratamentos em todos os métodos anteriores da pilha. Caso nenhum deles tenha algum tratamento, essa busca, que será exibida no stack trace, vai acabar no main pois não tem nenhum método antes dele na pilha. Interrompendo assim a aplicação ( erro ).

Edward, estuda um pouco sobre throw-throws que tu irá entender um pouco mais sobre o que acontece com as exceções.

Sobre a Thread… concordo que ela é morta e com a idéia do wellington sobre os objetos.

T

humm!! Tava lembrando disto agora mesmo!! É criada uma nova pilha! Vlw cara. A aplicação é finalizada?

E

Rapaziada deixa eu tentar explicar pra vcs oq ta pegando… não conheço quase nada de thread… só q estou tendo que dar manutenção em um processo aqui…

todos os usuarios da produção … quando clicam pra fazer um um processo do sistema aqui… e acionada uma thread…eles clicam toda hora… varias vezes no dia…
e como era um processo lento… colocamos em uma thread, para que o sistema não fique travado rodando o processo…
quando o usuario clica no botão é chamado este método
código abaixo

/** * Metodo que chama a thread de sincronizacao * @param ids */ private void threadSynchronize(List<Long> ids) { ThreadBuilder threadBuilder = new ThreadBuilder(); threadBuilder.withSynchronizeCampaign(synchronizeCampaign); Thread thread = new Thread(threadBuilder); thread.start(); }

depois que eu dou start() ele vai pra esse codigo

private synchronized void threadSynchronize(){
		BidLog.debug("Chamando thread de sincronizacao");
		
		int cont = 0;
		for (Long id : ids) {
			cont++;
			BidLog.debug("Campanha: " + cont);
			synchronizeCampaign.execSynch(id); 
		}
		BidLog.debug("Fim da execução da thread!");
	}

este método - > synchronizeCampaign.execSynch(id)
abaixo

public synchronized void execSynch(Long campaignID) {
		Campaign campaign = campaignListDAO.get(Campaign.class, campaignID);
		
		if (campaign.getTries() == -2) {
			setUpSponsorById(campaignID);
			submitCampaign(campaign);
			if(campaign.getId() == campaignID){
				message = getErrors(campaignID);
				if (message == null || message.equals(""))
					message = "Campanha " + campaign.getName() + " Sincronizada com Sucesso!";
			}else
				message = "Essa campanha não pôde ser sincronizada.Tente mais tarde.";

		    campaign.setTries(getStatusSincronizeBD(campaignID));
		    System.out.println("Tamanho da mensagem - > " + message.length());
			campaign.setMessage(message.substring(1,5));
			campaignListDAO.update(campaign);
			System.out.println("Campanha gravada");
			message = null;
		}
	}

quando está rodando este método … as vezes pode causar exceções … não tem problema … pode dar mesmo…

onde eu trato essas exceções??? …

cada usuario que clica pra fazer essa sincronização… as threads ficam na fila ou pilha nao sei rsrsr … por causa do synchronized …cada uma espera a outra terminar né??
pra depois começar outra thread rodar…

só q se a primeira thread que o usuario “A” clicou pra fazer o processo da exceções… parece que ela não termina de executar, ele não printa o codigo “BidLog.debug(“Fim da execução da thread!”);” que está no método la em cima… ela pára no meio do caminho parece…
e a thread do usuario “B” que estava aguardando o processo da “A” terminar … começa a rodar a thread dele …
mas com o tempo começa a ficar lento até estourar a memória… pq é um processo muito demorado…

quando não dá exceções todas as threads conseguem terminar sem ficar lenta…

E

esclarecendo um pouco mais, pq acho q ficou um pouco confuso

famos supor

o usuario A clica, logo em seguida o usuario B clica tbm no botão que faz este processo, e depois logo em seguida o usuario C tbm clica…

ai a thread do usuario A começa a rodar normal… enquando as outras ficam aguardando…

ai não deu exceção nenhuma no processo do usuario A… blz termina normal… e começa a thread no usuario B, nela causa uma exception px… ai ela não termina de rodar até o print que coloquei…
e automaticamente começa a rodar a thread do usuario C… depois de algum tempo começa a ficar lento … até dar estouro de memoria…

lembrando que são maio ou meno 20 thread esperando pra rodar…
se a thread 10 da uma exception… a 11 consegue roda… a 12 tbm… la pela 14 thread começa a ficar muito lento…até dar pau…

E

vou dar uma olhada…

vlwww… depois eu falo se deu certoo

W

Segue um exemplo com Thread que dispara exceção:

public class TesteThread {

	public static void main(String[] args) {
		MyThreadThrowException t = new MyThreadThrowException();
		//inicia a thread
		t.start();
		
		//Enquanto estiver viva, a main ficará parada.
		while(t.isAlive()){
			System.out.print('.');
		}
		
		//Verifica se a thread foi interrompida
		if(t.isInterrupted()){
			System.out.println("Interrupted");
		}
		
		//Se chegar aqui a thread não está mais viva...
		System.out.println("end");
		System.exit(0);
	}

}

class MyThreadThrowException extends Thread {
	@Override
	public void run() {
		
		//Um loop para fazer q a thread dure por algum tempo
		short i = 0;
		while(i++ < Integer.MAX_VALUE){
			if(i%Short.MAX_VALUE==0){
				System.out.println("\n"+i);
				//Dispara uma exceção
				throw new RuntimeException("erro thread");
			}
		}
		
		System.out.println("\nLoop finished");
		
	}
}

A exceção, quando é disparada na thread não chega até o main. Ela mata a thread.
Talvez o problema seja que objetos alocados não sejam finalizados (ou marcados para o GC coletar) e, no decorrer do dia, sobrecarreguem a memória fazendo que ocorram excessos de chamadas ao GC para manter a "integridade do sistema" (ou seja, não ocorra algum OutOfMemoryError) deixando o sistema lento.

W

edward.juniorr:
ah mais uma coisa

pra tratar algum erro q pode ocorrer dentro da thread eu faria assim??

Thread thread = new Thread(threadBuilder); try { thread.start(); } catch (Exception e) { thread.suspend(); thread.stop(); thread.interrupt(); thread.interrupted(); thread.destroy(); }

pq caso acontece alguma exception, tenho q mata-la… sei la fazer alguma coisa… para que o sistema continue normal…

caso seja isso … qual dos métodos eu uso pra tirar a thread da frente

Primeiro, coloque entre tags [ CODE ] os códigos que postar :wink:

Isso não serve de nada (exceto se ocorrer um erro no momento do start). Se a Thread iniciar com sucesso, já era, não vai mais estar dentro do bloco try-catch

W
Tiago.Argolo:
Certeza cara? Me corrija se eu estiver errado.. mas pelo o que eu entendi la na caelum a exceção irá buscar tratamentos em todos os métodos anteriores da pilha. Caso nenhum deles tenha algum tratamento, essa busca, que será exibida no stack trace, vai acabar no main pois não tem nenhum método antes dele na pilha. Interrompendo assim a aplicação ( erro ).

Em geral é isso o que acontece.
Só que, neste caso, foi criada uma Thread (até por isso que coloquei o exemplo). Ela não pertence mais à pilha de chamadas a métodos do método chamador (no caso, main). Ela terá sua própria pilha.

Teste o exemplo e veja o comportamento e o stackTrace gerado (segue abaixo):
Exception in thread "Thread-0" java.lang.RuntimeException: erro thread
	at MyThreadThrowException.run(TesteThread.java:33)
Veja que o trace não demonstra o método main Se vc comentasse o bloco
while(t.isAlive()){
			System.out.print('.');
		}
O método main ia terminar mas a Thread continua por mais um tempo (no caso, até ocorrer a exception). Fiz uma pequena alteração para demonstrar a diferença:
public class TesteThread {

	public static void main(String[] args) {
		MyThreadThrowException t = new MyThreadThrowException();
		//inicia a thread
		t.start();
		
		//Enquanto estiver viva, a main ficará parada.
		while(t.isAlive()){
			System.out.print('.');
		}
		
		//Verifica se a thread foi interrompida
		if(t.isInterrupted()){
			System.out.println("Interrupted");
		}
		
		System.out.println("end");
		
		try {
			dispararExecao(0);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.exit(0);
	}

	/**
	 * Criando uma stackTrace com recursão (5 chamadas)
	 * @param i
	 * @throws Exception 
	 */
	private static void dispararExecao(int i) throws Exception {
		if(i++ < 5){
			dispararExecao(i);
		}
		throw new Exception("forçando exceção");
	}

}

class MyThreadThrowException extends Thread {
	@Override
	public void run() {
		
		//Um loop para fazer q a thread dure por algum tempo
		short i = 0;
		while(i++ < Integer.MAX_VALUE){
			if(i%Short.MAX_VALUE==0){
				System.out.println("\n"+i);
				throw new RuntimeException("erro thread");
			}
		}
		
		System.out.println("\nLoop finished");
		
	}
}
Gerando outro StackTrace:
java.lang.Exception: forçando exceção
	at TesteThread.dispararExecao(TesteThread.java:38)
	at TesteThread.dispararExecao(TesteThread.java:36)
	at TesteThread.dispararExecao(TesteThread.java:36)
	at TesteThread.dispararExecao(TesteThread.java:36)
	at TesteThread.dispararExecao(TesteThread.java:36)
	at TesteThread.dispararExecao(TesteThread.java:36)
	at TesteThread.main(TesteThread.java:21)
Veja que aqui, o TesteThread.main(TesteThread.java:21) surgiu? :wink:
W

Só finaliza quando o main é finalizado (System.exit(0)) senão, só a Thread.

W

É difícil saber onde colocar um tratamento de exceção sem saber qual exceção que é, se é que a causa da lentidão é a exceção...

Não é pq não imprime que não "terminou". Se ocorrer um throw Exception, tudo que seria executado depois é literalmente ignorado.

De qualquer forma, tente:
private synchronized void threadSynchronize(){   
    BidLog.debug("Chamando thread de sincronizacao");   
       
    int cont = 0;   
    try {
        for (Long id : ids) {   
            cont++;   
            BidLog.debug("Campanha: " + cont);   
            synchronizeCampaign.execSynch(id);   
        }   
    } catch (RuntimeException e) {
        e.printStackTrace();
    }
    BidLog.debug("Fim da execução da thread!");   
}

Mas não garanto que vá resolver seu problema.
Você disse que estoura a memória, seria bom verificar a aplicação com ferramentas de profiling em busca de vazementos de memória.
http://www.guj.com.br/posts/list/196683.java
http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html

Criado 30 de abril de 2010
Ultima resposta 30 de abr. de 2010
Respostas 13
Participantes 3