Problemas com sincronizaÇÃo

6 respostas
D

Boa Tarde a todos,

estou com um problema que é o seguinte:
tenho um código que, basicamente, tem por objetivo preencher um determinado objeto com ~= 40 atributos. Por alguns motivos que não vem ao caso tive que optar por fazer a execução deste código utilizando o pattern reflection segue o trecho:

public synchronized ArrayList getData(ArrayList activia) {

		JImplements.setActivia(activia);
		control = Constants.systemName.length;

		for (int i = 0; i < Constants.systemName.length; i++) {

			try {

				JImplements aux = (JImplements) Class.forName(
						Constants.systemName[i]).newInstance();

				aux.addObserver(this);
				
				Thread t = new Thread(aux);
				t.setName(Constants.systemName[i]);
				t.start();

			} catch (Throwable e) {
				FileWriterLog.error("Erro ao coletar dados nos sistemas", e);
			}

		}

		try {
			super.wait();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return JImplements.getActivia();
	}
public class Savvion extends JImplements {

	public void returnData(ArrayList activia) {

		OraSiebelS oraSiebel = OraSiebelS.getInstance();
		OraSavvion oraSavvion = OraSavvion.getInstance();
		ArrayList sos = new ArrayList();
		ArrayList distancias = new ArrayList();

		oraSiebel.execute(activia);
		sos = oraSiebel.getSos();
		for (int k = 0; k < activia.size(); k++) {
			ActiviaVo act = (ActiviaVo) activia.get(k);
			for (int i = 0; i < sos.size(); i++) {
				SOS ss = (SOS) sos.get(i);
				if (act.getInstancia().equalsIgnoreCase(ss.getInstancia())) {
					act.setSosAtivas(ss);
					break;
				}
			}

		}
		oraSavvion.execute(sos);
		distancias = oraSavvion.getDistancias();
		for (int k = 0; k < activia.size(); k++) {
			ActiviaVo act = (ActiviaVo) activia.get(k);
			if (act.getSosAtivas() != null) {
				if (!"".equalsIgnoreCase(act.getSosAtivas().getRowid())) {
					for (int i = 0; i < distancias.size(); i++) {
						Distancia dist = (Distancia) distancias.get(i);
						if (dist.getRowId().equalsIgnoreCase(
								act.getSosAtivas().getRowid())) {
							act.setDistancia(dist.getDistancia());
							act.setSosCensup(dist.getRowId());
							act.setDistanciaArmario(dist.getDistanciaArmario());
						}
					}
				}
			}

		}

		synchronized (activia) {
			setActivia(activia);
		}
	}

[quote]public abstract class JImplements extends Observable implements Runnable {

public static ArrayList activia = new ArrayList();

public void run() {
try {
this.returnData(activia);
} catch (Throwable e) {

} finally {
this.update();
}

}
public static ArrayList getActivia() {
return activia;
}
public static synchronized void setActivia(ArrayList activia) {
JImplements.activia = activia;
}
public void update() {
super.setChanged();
super.notifyObservers();
}

/***/
public abstract void returnData(ArrayList activia);

}[code]

esse é o código que inicializa as duas threads(estou utilziando observer para fazer o controle...).

Cada uma dessas threads é responsável por preencher mais ou menos metade dos atributos dos meus objetos

o que está acontecendo é o seguinte as vezes a sincronização é feita corretamente e o objetos é populado com os dados enviados pelas duas threads e as vezes ele só é preenchido por apenas uma delas

e não estou conseguindo entender o pq, principalmente pelo fato de que isso ocorre de vez em quando.

Grato pela atenção

Leonardo De Bona

6 Respostas

pablosaraiva

É que o ArrayList não é “synchronized”.

Use Vector.

pablosaraiva

Verifique também se você está lendo o valor que está na zona de concorrência antes da finalização de todas as threads.

D

Eu tentei utilizar vector e o problema continua…

pablosaraiva

Também pode ser o seguinte.

Pelo que vi, você passa o Array como parâmetro para a sua thread.

Se a thread A receber o array intacto ao mesmo tempo que a thread B também receber o array intacto.

Vai valer apenas a resposta do que retornar o array por último.

O ideal seria, ao invés de passar o Array, ambas as threads acessarem o array de um local público, compartilhado.

E o synchronized cuidaria da concorrência.

D

hmm,

então eu poderia deixar apenas na minha classe abstrata o meu array,
e acessaria ele diretamente das minhas threads? Seria isso?

pablosaraiva

A classe nem precisa ser abstrata, mas o ArrayList deve ser static.

Criado 9 de dezembro de 2009
Ultima resposta 10 de dez. de 2009
Respostas 6
Participantes 2