Problemas com Threads! URGENTE! =(

Galera… To tentando desenvolver alguma coisa pra manipular a conexão com o banco de dados de tempo em tempo… Pra ser mais específico, estou tentando fazer um programa que verifique se a conexão com o banco de dados está ativa de tempo e tempo… Caso não esteja ele tenta reestabelecer a conexão… Também eu guardo um XML das operações enquanto a conexão não estiver estabelicida e ai eu envio pro banco quando conseguir estabelecer novamente… Não sei muito más acho que isso tem a ver com persistencia… não sei se estou fazendo da melhor maneira (aceito sugestões =) )… Bom… o que acontece é que eu gerei umas threads pra fazer esse temporizador e está travando minha interface gráfica… parece que o controle fica preso no while… não entendo… A thread não era pra rodar separadamente da interface???

Vejam meu código:

public class PersistenceController implements Runnable{

    public PersistenceController(Connection con, int time){
        bdcon = con;
        closed = false;
        
        sleep_time = time * 1000;
    }
            
    public void run() {
        do{
            Thread t1 = new Thread(new PersistenceRunnable(bdcon));
            try {
                t1.sleep(sleep_time);
            } catch (InterruptedException ex) {
               ex.printStackTrace();
            }
            
            t1.run();
        }while(!closed);
    }
    
    public void closePersistence(){
        closed = true;
    }

    private Connection bdcon;
    private boolean closed;
    private int sleep_time;
}





/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ginasticalaboral;

import java.sql.Connection;
import java.sql.DriverManager;

/**
 *
 * @author gs10123
 */
public class PersistenceRunnable implements Runnable {

    public PersistenceRunnable(Connection con) {
        bdcon = con;
    }

    public void run() {
        
        try {
            if (!bdcon.isValid(0)) {
                bdcon = DriverManager.getConnection("jdbc:mySQL://10.96.2.254:3306/srcdb", "root", "nopass");
            } else {
                System.out.println("Conexão válida!");
            }
        } catch (Exception e) {
            e.printStackTrace();

            System.out.println("Sem conexão.. Tentando mais tarde");
        }
    }
    
    private Connection bdcon;
}

Eu crio uma nova thread passando persistencecontroller como parametro no construtor da minha interface gráfica… ai para lá!!! :shock:

Tenta fazer isso através da SwingWorker.

Utiliza TimerTask, voce configura o tempo q deseja q ele execute o metodo run() do timer.

O método para iniciar uma thread é o start() não o método run().
O seu sleep também está sendo usado de uma maneira no mínimo estranha.

O código onde está o while, apesar de disparar várias threads, também não roda numa thread separada…

Que tal ler um pouco sobre Threads em Java, antes de tentar se aventurar na tentativa e erro?

Como ViniGodoy citou o método para iniciar a Thread é o .start(), se não não vai estar iniciando a mesma,
e você tá criando muitas threads, cada vez q passa pelo run() cria uma nova thread.
:?

Realmente eu não conheço muito Threads… ALguém pode me dar uma luz de como eu faço isso?

Olá!

O conceito é bem simples, nada que uma lida na documentação não ajude.

Quando você inicia o programa (metodo main), uma Thread é criada. Essa é a thread que vai ser executada até o final do programa e que realiza todas as chamadas de métodos normalmente. Quando vocÊ deseja que mais tarefas sejam realizadas paralelamente, você deve abrir uma nova Thread para cada tarefa. Pelo que pude entender, o que você quer é uma outra Thread que fique rodando em background (por trás da Thread principal), verificando a conexão de tempos em tempos e reabrindo-a quando necessário. Na implementação dessa nova Thread você coloca algo como:

enquanto programa_esta_rodando
    se DAO.obter_conexao.esta_inativa entao
        DAO.obter_conexao.ativar
    fim se

    esperar n segundos
fim enquanto

Uma pergunta, como seus objetos acessam o Connection que você deseja monitorar? Por meio de um Singleton?

Abraços

Cara… to vendo que isso vai dar mais dor de cabeça do q eu pensava…hahahahah…

Então… É isso mesmo… tanto é que consegui implementar o código… Ele fica de tempo em tempo vendo se a conexão está ok… senão cria uma nova conexão na variavel con… O problema agora é realemente esse … não sei como vou fazer pra meus objetos acessarem… vou ter vários lugares na minha aplicação que vou precisar desse objeto de conexão más não posso sair passando isso como parametro pra tudo quanto é lugar…

O Vini tava me falando que tem umas ferramentas prontas pra isso que eu to querendo… más também nunca vi… to meio sem saber o que fazer…

Procura por Singleton… é algo bem simples que resolve nesse caso. Esse pattern vai transformar seu Connection em um tipo de “variável global”, que poderá ser acessado de qualquer lugar da aplicação. Há algumas desvantagens, mas por enquanto vamos focar na resolução do problema.

Aa que massa… muito bom esse lance de variavel global… =)… Vou tentar assim então… Vlw mesmo garoto =)

Cara… eu vi sobre singleton… acho q resolve… O Problema agora é o seguinte… Minha aplicação fica rodando a thread em background, eu consigo validar quando a conexão caiu… porém… quando eu tiro o cabo de rede por exemplo e tento reestabelecer a conexão vem um milhão de exceptions e nunca reestabelece… Ficou complicado agora…

Alguém sabe alguma maneira de fazer isso? Utilizando ferramentas prontas… Talvez pool de conexões? Também vi que tem um opção autoReconnect que da pra passar pro Mysql… Bom… aceito sugestões ai pessoal…

Cara… eu vi sobre singleton… acho q resolve… O Problema agora é o seguinte… Minha aplicação fica rodando a thread em background, eu consigo validar quando a conexão caiu… porém… quando eu tiro o cabo de rede por exemplo e tento reestabelecer a conexão vem um milhão de exceptions e nunca reestabelece… Ficou complicado agora…

Alguém sabe alguma maneira de fazer isso? Utilizando ferramentas prontas… Talvez pool de conexões? Também vi que tem um opção autoReconnect que da pra passar pro Mysql… Bom… aceito sugestões ai pessoal…

Se a thread está disparando excessões com a desconexão, significa que a funçao básica dela (detectar problemas de conexão), está OK.

Agora só falta você tratar as excessões que ela dispara.

Trate as excessões (no catch) do tipo IOException, Exception, SocketException, EOFException, ConnectException e UnknownHostException.

Com isto, você tem em suas mãos todos os tipos comuns de erros de conexão sendo “monitorados”.

Caso ocorra um destes erros, no seu tratamento do catch envie um comando para a sua classe de controle principal para executar um método que vai tentar restabelecer a conexão por X vezes ou durante Y tempo, sempre lembrando de fechar ou setar como null a conexão anterior. Após enviar este comando, mate esta thread de monitoramento com um return e aguarde o método de reconexão.

Caso ele seja bem sucedido, inicie outra thread de monitoramento em cima dele. Caso o método não consiga a reconexão (servidor com fonte queimada, por exemplo), envie um aviso.

Uso este sistema aqui e funciona que é um doce.

EDIT: havia esquecido de colocar o UnknownHostException.

GabrielGarcia ,

PERFEITO!!! Cara… não sei nem como agradecer =)… vlw pela dica…

Meu erro era tentar reestabelecer a conexão direto na Thread… Como eu falei… não sei muito de Threads mesmo e vou seguir o conselho do vini pra estudar…

Do mais deu tudo certo… Crio a thread que fica verificando a conexão… se encontra erro chama método para reconectar… Asssim eu destrui a Thread antinga que na verdade só serve pra avisar que a conexão falhou e envia o controle para outro objeto reconectar… depois de tentar reconectar eu crio outra Thread para monitorar a conexão… Enfim… deu certo!!!

Obrigado todos que ajudaram ai… vlw mesmo…