Threads e exceptions

Eaê, galera, blz?

Tô implementando um sistema que lê informações de uma página da web e as grava numa base de dados local. No entanto, esse processo pode ser muito de demorado e, na minha aplicação, eu dou ao usuário a opção de interromper o processo no meio da execução. O problema disso é que eu não tinha como parar o processo do nada, daí, toda vez que encerrava o processo gerava uma exceção.

Para resolver isso, passei a utilizar Threads. Agora, para encerrar o processo, eu uso o método stop(). Isso me leva à primeira pergunta:

  • A documentação me diz que o método stop() está superado e que ele é perigoso. Mas, se eu utilizo threads com o único fim de poder encerrar o processo quando eu quiser, qual método devo utilizar/sobrescrever para garantir uma saída limpa?

O uso de threads me levou a um outro problema… Todos os métodos do meu importador lançam as exceções para o método chamador sem tratá-las. Esse tratamento de exceções eu fazia na minha interface gráfica, mostrando mensagens ao usuário e tomando atitudes. O problema é que, ao encapsular parte da minha lógica numa Thread, eu fico obrigado a tratar as exceções dentro do método run(), já que ele não lança exceções. Tentei inclusive pegar as exceções dentro do método e lançar uma RuntimeException, no entanto, esse tipo de exceção não pode ser capturada. Assim, minha segunda pergunta é:

  • Como eu faço para lançar uma exceção de dentro de uma thread, de modo que eu possa capturá-la fora da thread?

Obrigado pela atenção!

Nunca usei, mas veja isto:

http://java.sun.com/javase/6/docs/api/java/lang/Thread.UncaughtExceptionHandler.html

(Acho que isso é bom até para mim também. Estou com um programa Swing gigantesco para manter aqui, preciso ver se isso poderia ajudar um pouco.)

Bom, vamos por partes.

Quanto ao stop o que é recomendado é que você crie seu método de parada como no exemplo abaixo.


  public class MeuProcesso implements Runnable {

   private boolean cancelado;


   public void run() {

       while (!cancelado) {
          //  Fica executando aqui
       }

   }

   public void cancelarProcesso() {
        cancelado = true;
   }

  }

Agora você tem que ver dentro da sua implementação como usar a mesma lógica para parar seu thread.

Quanto a questão das exceptions você pode usar algo como uma pattern Observable para capturar a exception dentro do thread e redirecionar para alguma tela da sua aplicação.

Cuidado. Como a variável cancelado será acessada por duas Threads, ela deve ser declarada como volatile ou sempre ser usada dentro de um bloco sincronizado.

Além do método que o colega descreveu, procure também tratar corretamente a InterruptedException, fazendo que sua thread pare sempre que receber uma interrupção dessas.

Também estou com este problema.
Alguém conseguiu solução?

Então porque não usam a infraestrutura do Executor? Ou Future? Eles tem mecanismos mais inteligentes para Stop ou cancelamento de threads. Na verdade essa que é a abordagem indicada…

Tem razão.

Como ficaria usando estas classes citadas?
Desde já agradeço.

É… confesso que é meio complexo… Dá uma olhada na API para entender melhor… Mas nada mais é do que passar um Runnable para o Executor e startar o Executor… Se der tempo mais tarde (depois do experiente) eu posto aqui algum exemplo…

Eu te agradeço, vou dar uma olhada na API sim.
obrigado.

http://www.guj.com.br/posts/list/50321.java#264645

[quote=ViniGodoy][quote=kaoe]
Bom, vamos por partes.

Quanto ao stop o que é recomendado é que você crie seu método de parada como no exemplo abaixo.

[/quote]

Cuidado. Como a variável cancelado será acessada por duas Threads, ela deve ser declarada como volatile ou sempre ser usada dentro de um bloco sincronizado.

Além do método que o colega descreveu, procure também tratar corretamente a InterruptedException, fazendo que sua thread pare sempre que receber uma interrupção dessas.[/quote]

O que nos leva a concluir que o jeito certo de parar uma thread é chamando thread.interrupt();
Isso de condição de paragem é quando existe uma logica de paragem. no caso aqui existe a ação especifica de parar a thread e isso é feito com interrupt.