Thread (Comunicação entre elas)

11 respostas
S

Tenho duas threads que executam funções distintas.

Thread A : Inicializa as configurações de usuario, senha e etc para o banco.

Thread B: Fica dormindo durante 10 segs. Esta necessira que thread A já tenha terminado seu trabalho.

Como eu faço a Thread A dizer para Thread B, pare de dormir e continue seu trabalho!

Alguem pode me ajudar?

11 Respostas

Felagund

thread.join();

a proxima excecução sera somente quando a thread terminar, e isso pode demorar, você não tem como saber quando uma thread vai terminar, vc pode tentar passar atributos para a outra thread, um boolean talvez e assim usar para executar as ações da 2 thread.

ffranceschi

Voce pode usar também os metodos wait e notify da Thread - http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#notify()

M

Quanto ao wait e notify, cuidado com deak locks e live locks.

Mais sobre concorrência em http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html

ffranceschi

Pelo que ele explicou parece ser duas threads que nem vao ser acionadas concorrentemente… o maior problema eh gerenciar várias threads…
Eu particularmente prefiro usar “jms” sempre que possivel, assim tenho garantia de execução.
O que realmente faz essas duas threads? e pra que voce precisa delas?

S

Vou explicar melhor

Quando o sistema que desenvolvi é iniciado a conexão com o banco deve ser configurada através de um arquivo, e caso a senha do usuário esteja errada por exemplo, acontece um delay muito grande, pois o hibernate fica tentando a conexão com banco por um bom tempo.

Esta executa um comportamento da classe ConfiguracaoBanco.

public void run()
    {         
         pegaConfiguracoesBancoDados();  //pega configuração e inicia o banco      
    }

Esta executa um comportamento da classe Gui_Acesso
Este outro thread verifica se existe algum usuário com poderes administrativos cadastrado no sistema.
Como eu sei que é a primeira transação com banco caso acontece um RuntimeException sei que não foi possível conexão com banco, aviso o usuário, fecho o programa, e na próxima execução, abro um gerenciador de configuração com banco de dados para que a conexão possa ser re-configurada.
Este thread quando entra em execução de cara é colocada pra dormir. Eu gostaria de esperar no Maximo 9 segundo, mas não sempre até 9 segundos; Caso a outra thread termine seu trabalho antes de 9 segundo gostaria de liberar a thread abaixo para sua execução;

try
        {
            Thread.sleep(9000);
            jButton1Loggin.setEnabled(true);

            boolean verifica = Usuario.verifica_Existencia_Administrador_Do_Sistema_NoBanco();
            if(verifica == true)
            {
                 System.out.println("Usuario Administrador existe");
            }
            else
            {
                RegistroUsuarioSistema registro = new RegistroUsuarioSistema();
                registro.modoAdministrador();
                registro.setVisible(true);
            }

        }catch(InterruptedException e)
        {

        }catch(RuntimeException e)
        {
            JOptionPane.showMessageDialog(this, "Não foi possível obter uma conexão com o banco de dados\n" +
                                                "Reinicie o programa e verifique se as configurações com o banco estão corretas\n\n" +
                                                "Caso seja necessário entre em contato com o suporte.", "Erro: Banco de Dados", JOptionPane.INFORMATION_MESSAGE);

           InfoServidorDados conf = new InfoServidorDados();

           try
           {
                conf.setServidor(false);
                System.exit(0);

           }catch (FileNotFoundException ex)
           {
               ex.printStackTrace();
           }catch (IOException ex)
           {
                ex.printStackTrace();
           }


        }

Isso funciona, mas gostaria de agilizar o processo.
Vocês acham que isso tam com mal cheiro?

S

Só para ficar claro.

Estas duas thread não acessam objetos compartilhados.

ffranceschi

Na primeira vez que o usuario abre o sistema ele teria que configurar a conexão com o banco, entao o que acha de logo q ele clicar no botao testar a conexao com o banco de dados, sem criar thread nenhuma? Por que deixar o usuario entrar no sistema sendo que caso ele tenha digitado os parametros do banco de dados errado, ele nao teria nenhuma informação?

S

Essa solução já me passou pela cabeça.

Mas da forma que esta feito o usuário não entra no sistema quando configura o banco.
Vai para tela de loggin, e lá acontece o aviso caso as configurações estejam erradas.

Vou repensar isso. (Ficaria bem agradavel um botão para testar a coneção)

Bom, agora falando de minha duvida.
Pesquisei em muitos livros, e não encontrei nada.

Não tem como dois threads de contextos diferentes (que não compartilham o mesmo objeto) serem sincronizadas da forma como eu quero?!

ffranceschi

Pelo que entendi, vc tem as 2 threads, A e B. A thread B só é iniciada qdo a thread A acabar.
Se for isso, pq teria duas threads? Mas se quisesse com duas threads, há algumas formas de resolver isso:

  1. Criar a thread B quando a thread A acabar
  2. Criar as duas threads e usar o wait e notify
  3. Tem o join como citado
S

ffranceschi:
Pelo que entendi, vc tem as 2 threads, A e B. A thread B só é iniciada qdo a thread A acabar.
Se for isso, pq teria duas threads? Mas se quisesse com duas threads, há algumas formas de resolver isso:

  1. Criar a thread B quando a thread A acabar
  2. Criar as duas threads e usar o wait e notify
  3. Tem o join como citado

Thread A e B são iniciados quase que ao mesmo tempo.

Só que thread B dorme 10 segundos na esperança de que A tenha terminado seu trabalho para continuar o seu.

O problema exige dois threads, pois estou visualizando possíveis exceções no uso do programa. Deixa-me explicar.

Suponha-se que eu coloque um botão para testar a conexão do banco na tela de configuração, como você havia me dito.
Esse código abaixo será executado para iniciar a conexão com o banco, caso todas as informações estejam corretas é rapidinho. Agora, se alguns dos parâmetros forem inválidos, o trabalho se torna exaustivo (Demorando cerca de 1 minuto ou mais). Isso trava minha aplicação.

public void inicia(String bd, String user, String ssn)
    {
        try
        {
              cfg = new Configuration().configure().setProperty(Environment.URL,bd).setProperty(Environment.USER, user).setProperty(Environment.PASS, ssn);
              sessionFactory = cfg.buildSessionFactory();   
        }
        catch(Throwable e)
        {
            new ExceptionInInitializerError(e);          
        }


    }

Qual a minha solução.
Coloco um Thread para iniciar o banco, e outro que apos 9 segundos dormindo, tenta abrir uma sessão com o banco, caso não haja conexão isso me retorna um runTimeException e eu aviso o usuario para configurar novamente o banco.

maior_abandonado

bom… eu não li tudo mais… acho que pode lhe servir

o join talvez nao fosse a melhor opção por que vc tem um tempo maximo a se esperar… ja o join esperaria o tempo q fosse

o metodo wait tem uma sobrecarga que recebe um long de milisegundos, ou seja, o tempo maximo a se esperar(algo como 9000 para 9 segundos)

caso a thread A termine antes ela sincroniza e da um notify na thread B… ai a B vai sai do estado de espera quando for notificada ouapós 9 segundos… o q vier antes, confirma se a thread A conseguiu executar o q devia (dexa um boolean pra thread A coloca true se tiver conseguido)… e o q vier depois vc q sabe…

espero q isso não seja bestera por eu nao ter intendido ja que não li tudo…rs

Criado 25 de fevereiro de 2009
Ultima resposta 26 de fev. de 2009
Respostas 11
Participantes 5