Futuredo java.util.concurrent continua executando mesmo mesmo após execedido o time-out[Resolvido]

6 respostas
D

Boa tarde pessoall.

Seguinte tenho um metodo que tem tempo deteminado para executar. Seguindo orientação do pessoal aqui do forum resolvi a classe Future do pacote java.util.concurrent. Segui a baixo minhas classes:
import java.util.concurrent.Callable;
import java.util.concurrent.ScheduledThreadPoolExecutor;

public class GeraNotaUtil  implements  Callable<Veiculo> {
   Movimentacao movimentacao=null;
   GerarNfseResposta resposta=null;
 
   
   public GeraNotaUtil(Movimentacao movimentacao){
	super();
	this.movimentacao = movimentacao;
    }
   @Override
    public Resposta call() throws TempoDeRespostaExecedeuLimiteConfiguradoException, ErroDeAutenticacaoException,     ErroAOCriarXMLEnvioException, ErroAoAssinarConteudoException, ErroNaGeracaoNotaFiscalException  {
		// TODO Auto-generated method stub
		
	   
		resposta=NotaFiscalUtil.gerarNotaFical(Veiculo);
	    return resposta;
	}

}

E minha classe que executa a operação:

public  static   GerarNfseResposta obterNotaFiscal(Veiculo veiculo) throws InterruptedException, ExecutionException{
	  ScheduledThreadPoolExecutor executor =new ScheduledThreadPoolExecutor(1);
	  executor.allowCoreThreadTimeOut(false);
	  Future future = executor.submit(new GeraNotaUtil(veiculo));   
	  GerarNfseResposta resposta=null;
	  try {
		 resposta=(Resposta) future.get(1,TimeUnit.SECONDS);
	} catch (TimeoutException e) {
		// TODO Auto-generated catch block
		executor.shutdown();
		executor.shutdownNow();
		future.cancel(true);
		
		
		throw new TempoDeRespostaExecedeuLimiteConfiguradoException("TEMPO DE RESPOSTA EXCEDEU O TEMPO DE LIMITE CONFIGURADO");
	}  
    return resposta;
  
  }

O probelma é o que ela é lançado o timeOut, mas a execução continua.
Tentei usar os metodos cancel e Shtudoen no excption mas não funcionou.
Eu agradeço qualquer sugestão.

6 Respostas

ViniGodoy

Mas o que exatamente você quer?

Uma vez iniciada a execução de um método, não tem como para-lo na metade. O máximo que você pode fazer é criar um flag, e ficar testando.

doSomething(); if (timeoutExceeded) return; doSomethingElse(); if (timeoutExceeded) return; doEvenAnotherThing(); if (timeoutExceeded) return;

Se seu código estiver num loop, fica mais fácil, já que esse flag pode ser a condição de saída.

E

Continua mesmo. Uma thread não pode ser interrompida “externamente”, mesmo com Thread.interrupt, se não houver colaboração dela.

D

Justamente eu quero parar a execução assim que exceder o timeout.
Não seria possivel o Pool de thread me devolver a thread que está rodando e eu dá um interrupt.
Será que realmente não existe um meio de parar o metodo no mieio da execução.

E

Você não entendeu.

Mesmo se você conseguisse executar Thread.interrupt, o máximo que isso faz é gerar uma exceção InterruptedException em algum lugar da sua thread que esteja preparada para lançar essa exceção (por exemplo, se sua thread estiver executando Thread.sleep, ou se sua thread estiver rodando em Unix e estiver executando alguma operação de I/O).

O correto, como disse o Vinicius Godoy, é checar uma flag dentro da sua thread, para que ela saia conforme for necessário.

sergiotaborda

Para usar features avançadas vc precisa entendê-las. Demos-te a dica,mas precisas estudar como se usa.

O timeout não é problema é a solução. Se o timeOut acontece quer dizer que o tempo passou sem que o metodo completásse
ai tens que retornar null ou sei lá e pronto. cancelar o futuro depois que ele deu timeout é inutil.

A exceção significa isso. portanto vc simplesmente dá returno null e pronto.

O executor tem que ser finalizado no finally e não no catch. ou melhor ainda ele deve ser estático.

public  static   GerarNfseResposta obterNotaFiscal(Veiculo veiculo) {  
  ScheduledThreadPoolExecutor executor =new ScheduledThreadPoolExecutor(1);  
  executor.allowCoreThreadTimeOut(false);  
  Future future = executor.submit(new GeraNotaUtil(veiculo));     

  try {  
     return (Resposta) future.get(1,TimeUnit.SECONDS);  // bloqueia aqui
} catch (TimeoutException e) {  
    return null;
}  catch (InterruptedException e){
    // a execução foi interrompida pela jvm , não ha timeout, mas tb não completou corretamente
    // no-op 
} catch (ExecutionException e){
   //wrapper de exceções dentro do caller.
   throw new RuntimeException(e.getCause());
}

O método faz exatamente o que vc queria. Qual é o problema agora ?

D

Dei lida melhor, e funcionou perfeitamente.
No meu caso apenas aviso que timeOut continua e permaneço com thread em execução.
Muito obrigado.

Criado 18 de novembro de 2009
Ultima resposta 27 de nov. de 2009
Respostas 6
Participantes 4