Duvidas na Utilização de Thread

5 respostas
GraGarcia

Bom dia a todos!

Estou desenvolvendo um programa para coletar as informações que estão trafegando na porta serial, mais precisamente: tenho um medidor de vazão de leite na outra ponta e preciso coletar a quantidade que está sendo coletado.

Após inúmeros garimpos pelo fórum cheguei ao seguintes métodos:
public void LerDados(){
        if (Leitura == true){
            try {
                entrada = porta.getInputStream();
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null,"Erro.STATUS: " + e);
                System.exit(1);
              }
            try {
                porta.addEventListener(this);
//                JOptionPane.showMessageDialog(null,"SUCESSO. Porta aguardando...");
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null,"Erro ao criar listener. STATUS: " + e);
                System.exit(1);
              }
            porta.notifyOnDataAvailable(true);
            try {
                threadLeitura = new Thread(this);
                threadLeitura.start();
                run();
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null,"Erro ao iniciar leitura: " + e);
              }
        }
    }
   
    //método RUN da thread de leitura
    public void run(){
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null,"Erro. Status = " + e);
          }
    }
    
    //gerenciador de eventos de leitura na serial
    public void serialEvent(SerialPortEvent ev){
        switch (ev.getEventType()) {
            case SerialPortEvent.BI:
            case SerialPortEvent.OE:
            case SerialPortEvent.FE:
            case SerialPortEvent.PE:
            case SerialPortEvent.CD:
            case SerialPortEvent.CTS:
            case SerialPortEvent.DSR:
            case SerialPortEvent.RI:
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
            break;
            case SerialPortEvent.DATA_AVAILABLE:
            byte[] bufferLeitura = new byte[20];
            try {
                while ( entrada.available() > 0 ) {
                    nodeBytes = entrada.read(bufferLeitura);
                }
                String Dadoslidos = new String(bufferLeitura);
                
                telaPrincipal.jlsQtdMed.setText(Dadoslidos);
                  
                while ( entrada.available() > 0 ) {
                    JOptionPane.showMessageDialog(null, Dadoslidos);
                }
                if (bufferLeitura.length == 0) {
                    linArq = "Nada foi lido!";
                    GerarArquivo(linArq);
                } else if (bufferLeitura.length == 1 ){
                    linArq = "Apenas um byte foi lido!";
                    GerarArquivo(linArq);
                } else {
                    linArq = "LIDO: " + Dadoslidos;
                    GerarArquivo(linArq);
                    
                    telaPrincipal.jlsQtdMed.setText(Dadoslidos);
                    
                    String lido = Dadoslidos.replaceAll("\\D", "");
                    JOptionPane.showMessageDialog(null, "Somente número: " + lido);
                    
                    sSql = "Update Usu_T001Med Set Usu_QtdMed = (?) Where Usu_NumSer = (?)";
                    try{  
                        PreparedStatement prepared = conn.prepareStatement(sSql);  
                        prepared.setString(1, Dadoslidos);  
                        prepared.setString(2, infBanco.get(5).toString());  
                        
                        JOptionPane.showMessageDialog(null, "SQL: " + sSql);
                        
                        prepared.executeUpdate();  
                    }catch (SQLException e){  
                        e.printStackTrace();  
                    }
                }
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null,"Erro durante a leitura: " + e);
              }
            break;
        }
    }

Da forma com que o código está coleta as informações do medidor durante 10 segundos até que a Thread é finalizada, sei que é por causa do método sleep, tentei tirar ele mas minha leitura do serial para de funcionar. Gostaria de deixar o método de coleta executando até que estiver passando leite no medidor de vazão, após o termino ai sim finalizar a Thread.

Obs.: Desculpe se o código acima está nada apresentável, é que estou tentando fazer funcionar e entender o processo primeiramente, para depois melhorá-lo.

Att,
Graziani Garcia

5 Respostas

E
threadLeitura.start();  
                run();

Por que é que você chama o método “run” indiretamente (via start) e diretamente (via chamada de run)?

De modo geral, acho muito confusos códigos que se escrevem e que usam “new Thread (this)”. Normalmente eles indicam que há alguma confusão mesmo.

De qualquer maneira, não há problema nenhum em usar Thread.sleep para esperar alguma coisa ocorrer - você pode até ficar em um loop, mais ou menos assim:

while (alguma coisa não ocorreu) {
    try { Thread.sleep (100); } catch (InterruptedException ex) { .... }
}

Acho mais fácil e dá menos problemas que aqueles truques que os professores usam de chamar “wait” e “notify”, que são coisas de nível muito baixa e não devem ser usadas em código normal - elas são o análogo do “goto”; uso excessivo de wait e notify indica que vai haver problemas muito sérios de manutenção mais tarde.

Só que você está confundindo um monte de coisas.

GraGarcia

entanglement, obrigado pela atenção,

Confundindo devo estar mesmo, pois não sou programador, e não conheço a linguagem a fundo, estou tentando minimizar os problemas que estou tendo aqui na empresa.

Vou quebrar mais um pouco a cabeça e tentar seguir o que você me disse na questão do loop, o que ainda não consegui identificar é o momento em que o evento inicia, no caso o momento em que á dados trafegando na porta serial.

sergiotaborda

eu não entendi se você quer obter os dados em intervalos de tempo ou se quer obtê-los “continuamente”

Se for em intervalos de tempo use a classe timer , ou melhor ainda use o ScheduleExecutorService
Se for “continuamente” , esqueça. User intervalos de tempo mais pequenos (1 milisegundo, por exemplo). Mas acho que para a vazão, se meio em mio segundo seria suficiente.

GraGarcia

sergiotaborda, vlw pelo retorno.

Tenho que realizar continuamente esta leitura.

Eu entendi o que você me passou, só não sei ainda como fazer, mas eu vou conseguir…rs

M

O método run nunca deve ser utilizado por você mesmo, para ler de meio em meio segundo basta colocar 500 no tempo, instancie a sua classe que implementa runnable a coloque como objeto dentro da thread. E poste erros.

Criado 3 de janeiro de 2013
Ultima resposta 4 de jan. de 2013
Respostas 5
Participantes 4