Multiplas Threads acessando a mesma lista?

2 respostas
leoviniga

Segue o código:

public class JanelaJogo extends JPanel implements Runnable {

	private AffineTransform transform = new AffineTransform();
	private ArrayList<Obstaculo> obstaculosVirtuais;
	private ArrayList<Obstaculo> obstaculosReais;
	private long tempoParcialNovo;
	private long tempoParcialDescer;
	private long tempoAtual;
	private long tempoInicial;
	private int nivel;

	public JanelaJogo() {
		obstaculosReais = new ArrayList<Obstaculo>();
		obstaculosVirtuais = new ArrayList<Obstaculo>();
		obstaculosVirtuais.add(new Obstaculo());
		nivel = 0;
		tempoInicial = System.currentTimeMillis();		
		new Thread(this).start();
	}

	public void run() {
		tempoParcialNovo = System.currentTimeMillis();
		tempoParcialDescer = System.currentTimeMillis();
		while (true) {
			tempoAtual = System.currentTimeMillis();
			
			if (tempoAtual - tempoInicial >= nivel * 3000 && nivel < 10) {
				nivel++;
				System.out.println("Nível = " + nivel);
			}
			
			if(tempoAtual - tempoParcialNovo >= 1050 - (nivel * 100)){
				adicionarObstaculo();
				tempoParcialNovo = System.currentTimeMillis();
			}
			
			if(tempoAtual - tempoParcialDescer >= 35 - (nivel * 3)){
				tempoParcialDescer = System.currentTimeMillis();
				ArrayList<Obstaculo> l = new ArrayList<Obstaculo>();
				for (Obstaculo obs : obstaculosVirtuais) {					
					obs.setY(obs.getY() + 1);
					
					int mouseX = MouseInfo.getPointerInfo().getLocation().x;
					int mouseY = MouseInfo.getPointerInfo().getLocation().y;					
					Point ponto = new Point(mouseX, mouseY);
					SwingUtilities.convertPointFromScreen(ponto, this);
				
					mouseX = (int)ponto.getX();
					mouseY = (int)ponto.getY();
					
					if(mouseX - (obs.getX() + 13) < 12 && mouseX - (obs.getX() + 13) > -12){
						if(mouseY - (obs.getY() + 13) < 12 && mouseY - (obs.getY() + 13) > -12){							
							JOptionPane.showMessageDialog(this, "Você perdeu, volte ao nível 1");							
							nivel = 0;
						}
					}
					
					l.add(obs);					
				}
				obstaculosVirtuais = l;
				obstaculosReais = l;
				repaint();
			}
		}
	}

	private void adicionarObstaculo() {
		obstaculosVirtuais.add(new Obstaculo());
	}

	public void paintComponent(Graphics g) {
		Graphics2D g2d = (Graphics2D) g;
		super.paintComponent(g2d);

		setBackground(Color.WHITE);

		for (Obstaculo obs : obstaculosReais) {
			if (obs.getY() < 650) {
				g2d.setTransform(transform);
				obs.setY(obs.getY() + 1);
				g2d.drawImage(obs.getForma(), obs.getX(), obs.getY(), null);
			} else {
				obstaculosVirtuais.remove(obs);
			}
		}
		obstaculosVirtuais.trimToSize();
	}
}

Está ocorrendo o erro:

Exception in thread "Thread-2" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:782)
	at java.util.ArrayList$Itr.next(ArrayList.java:754)
	at visual.JanelaJogo.run(JanelaJogo.java:56)
	at java.lang.Thread.run(Thread.java:636)

Sei que esse erro ocorre quando você tenta alterar uma Lista enquanto lê a mesma mas não estou sabendo contornar esse erro nesse caso, até substitui uma das threads que eu estava usando por IF’s e nada.
Talvez eu não esteja olhando no lugar certo ou talvez não tenha conhecimento suficiente de threads já que é mnha primeira vez usando isso.

Agradeço a ajuda desde já.

EDIT: O erro aponta para a linha 40.

2 Respostas

T

Utilize o synchronized na variável que representa a lista dentro da funcao…

E

Tenta isso:

List list = Collections.synchronizedList(arrayList);

Ou usa um Hashtable.

Criado 9 de dezembro de 2011
Ultima resposta 9 de dez. de 2011
Respostas 2
Participantes 3