Ho un programma java che è fondamentalmente un gioco. Ha una classe denominata "Mondo". La classe "Mondo" ha un metodo 'levelChanger()' e un altro metodo 'makeColorArray()'.Come interrompere un thread dalla modifica di un array che viene utilizzato da un altro thread?
public class World {
private BufferedImage map, map1, map2, map3;
private Color[][] colorArray;
public World(int scrWd, int scrHi) {
try {
map1 = ImageIO.read(new File("map1.png"));
map2 = ImageIO.read(new File("map2.png"));
map3 = ImageIO.read(new File("map3.png"));
} catch (IOException e) {
e.printStackTrace();
}
map = map1;
makeColorArray();
}
private void makeColorArray() {
colorArray = new Color[mapHi][mapWd]; // resetting the color-array
for(int i = 0; i < mapHi; i++) {
for(int j = 0; j < mapWd; j++) {
colorArray[i][j] = new Color(map.getRGB(j, i));
}
}
}
//color-array used by paint to paint the world
public void paint(Graphics2D g2d, float camX, float camY) {
for(int i = 0; i < mapHi; i++) {
for(int j = 0; j < mapWd; j++) {
if(colorArray[i][j].getRed() == 38 && colorArray[i][j].getGreen() == 127 && colorArray[i][j].getBlue() == 0) {
//draw Image 1
}
else if(colorArray[i][j].getRed() == 255 && colorArray[i][j].getGreen() == 0 && colorArray[i][j].getBlue() == 0) {
//draw Image 2
}
}
}
}
public void levelChanger(Player player, Enemies enemies) {
if(player.getRec().intersects(checkPoint[0])) {
map = map2;
//calls the color-array maker
makeColorArray();
}
else if(player.getRec().intersects(checkPoint[1])) {
map = map3;
makeColorArray();
}
}
public void update(Player player, Enemies enemies) {
levelChanger(player, enemies);
}
}
Procedimento makeColorArray() libera matrice 2D di tipo 'colore'. Questo array memorizza oggetti colore da un'immagine PNG. Questo array è usato dal metodo paint() di JPanel per dipingere il mondo sullo schermo.
Il metodo levelChanger() viene utilizzato per modificare i livelli (fasi) del gioco quando una determinata codifica è vera. È il metodo con cui chiama il metodo makeColorArray() per ricreare l'array di colori durante la modifica del livello di gioco.
Il problema è che ho un ciclo di gioco che gira su una discussione. Ora, la pittura di componenti swing come JPanel viene eseguita su un thread in background diverso da java. Quando viene modificato il livello del gioco, viene ricreato l'oggetto color-array. Ora, come ho detto in precedenza, l'oggetto color-array è usato dal metodo paint() per dipingere il mondo sullo schermo. A volte, l'oggetto color-array viene ancora utilizzato dal thread in background (non finito di dipingere) quando, in base alla logica di gioco, l'oggetto color-array viene ricreato ei suoi membri vengono impostati su null. Ciò causa l'eccezione null-pointer solo occasionalmente. Chiaramente una condizione di gara.
Desidero sapere come posso interrompere il thread di gioco dal ripristino della matrice di colori fino a quando il thread di oscillazione dello sfondo ha finito di dipingere.
vi suggerisco di guardare in biblioteca concorrenza java: http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html – dckuehn
La soluzione migliore è quella di non utilizzare più thread. Sostituisci il ciclo principale con 'javax.swing.Timer' o usa' SwingUtilities.invokeAndWait'. –
@Banthar è una soluzione semplice per il problema ma non è la migliore per tutti i casi. Se il codice di aggiornamento è un processo che richiede molto tempo per essere elaborato, spostarlo nell'EDT impedisce che gli eventi di UI reali vengano elaborati in modo tempestivo e tempestivo. – NESPowerGlove