Sincronizacao de Objetos[RESOLVIDO]

4 respostas
vcsmetallica

Galera, sei que tem muita coisa na net sobre isso. Mas nao consegui achar uma solução para o meu problema.

PROBLEMA

Tenho 2 threads, uma que representa um servidor de socket - Thread1 e uma outra que trabalha as conexoes que foram armazenadas em uma lista Thread2. De acordo com a documentação do projeto eu tenho que pegar uma conexao de um equipamento e colocar ele em uma lista.
Quando vou usar essa lista na Thread2 esta dando java.util.ConcurrentModificationException como ja era de se esperar. Sincronizei os meu metodos, como descrito na classe abaixo. Outra coisa, nao posso colocar um sleep na Thread1, devido a conexao de equipamentos. Quando o equipamento solicitar uma conexao o servidor tem que estar alerta, nao pode estar dormindo igual vigia nortuno!!! Mesmo usando sleep na Thread2 ocorre java.util.ConcurrentModificationException, por que é nessa theard que vou fazer a validação dos equipamentos e enviar comandos para eles. Esse processo leva alguns segundos, pq estou acessando a base de dados.

abaixo os exemplos que estou tentando rodar

Classes

public class ServerTrataConexao implements Runnable {

    private Numeros numeros;

    public ServerTrataConexao() {

    }
    public ServerTrataConexao(Numeros s) {
        numeros = s;
    }

    private void mostrarDados() {
        try {
            while (true) {
                //Aqui eu trato as conexoes que foram
                //Armazenadas no meu List
                 Thread.sleep(1000);
                List<Integer> valor = numeros.getNumeros();

                for (Integer i: valor) {
                    System.out.println("Valor da vez: " + i);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run() {
        mostrarDados();
    }
}

public class ServerSocket implements Runnable {

    private Numeros numeros;

    public ServerSocket(Numeros s) {
        numeros = s;
    }

    private void inserirNumeros() {
        try {
            //Suponhamos que aqui esta o meu servidor socket aguardando
            //novas conexoes.
            while (true) {
               int numero = (int)(Math.random() * 100000);
               numeros.setNumeros(numero);
               Thread.sleep(50);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void run() {
        inserirNumeros();

    }
}

public class Numeros {

    private  List<Integer> numeros = new ArrayList<Integer>();

    public synchronized  void setNumeros(Integer numero1) {
        numeros.add(numero1);
    }

    public synchronized  List<Integer> getNumeros() {
        return numeros;
    }
}

Sei que o tema é bem antingo, nao sei se alguem ja passou por isso que estou passando.

Att

4 Respostas

ViniGodoy

O seu while do mostraDados não tem nada de sincronizado.
Não é só pq vc obtém uma referência à lista de maneira sincronizada, que seu acesso a lista é sincronizado.

O erro de ConcurrentModificationException ocorre sempre que uma lista é modificada enquanto é percorrida. Você não precisa nem de multiplas threads para isso, basta chamar métodos como remove ou add dentro de um for each.

Ao invés de sleep, procure se informar sobre o wait() e notify() e sobre a classe java.util.synchronized.LinkedBlockingQueue.

vcsmetallica

Entao,
pesquisei mais um pouco na net e achei isso

while (true) {
               
                 List<Integer> valor = Collections.synchronizedList(new ArrayList<Integer>(numeros.getNumeros()));
                synchronized (valor) {
                    System.out.println("Tamanho da lista: " + valor.size());
                   
                    for (Integer i : valor) {
                        //System.out.println("Valor da vez: ");
                    }
                }
            }

Agora vou ver se da certo na minha aplicação, pq aqui no meu exemplo deu certo.

Valeu pela ajuda

ViniGodoy

Se você quiser evitar dores de cabeça fortes, recomendo com extrema vêemencia que você pare um pouco, estude threads e sincronização, para só depois voltar ao seu software.

Não se programa multi-threads a base da tentativa e erro, nem copiando e colando de tutoriais sem entender exatamente o que está acontecendo.

Problemas de sistemas multi-thread são muito mais difíceis de reproduzir ou corrigir. É loucura enviar um sistema para produção sem entender certinho como as coisas funcionam.

vcsmetallica

Valeu pela dica, por isso é que gosto desse forum.
Entao, ja tenho alguma vivencia de thread, ja passei mals boccados com thread em sistemas em producao, mas nao nesse nivel. O problema é que eu nunca havia trabalhado com lista sincronizada, geralmente é um objeto que eu sincronizava e boa.

Valeu mais uma vez pela força irmão!

Att

Criado 14 de julho de 2011
Ultima resposta 14 de jul. de 2011
Respostas 4
Participantes 2