Witam. Mam obiekt, który zwraca obrazki w ten sposób, aby tworzyła się animacja. Klasa tego obiektu wygląda w ten sposób:
public class AnimatedObject {
//Wszystkie "ramki"
private Image[] images = new Image[4];
//Aktualna "ramka"
private int image = 0;
public AnimatedObject() {
/*
* ZAŁADOWANIE
* WSZYSTKICH
* OBRAZKÓW
*/
//Uruchomienie wątku
new AnimationThread().start();
}
//Metoda która zwraca aktualny obrazek obiektu
public Image getImage() {
return images[image];
}
//Wątek odpowiedzialny za zmianę aktualnego obrazka
private class AnimationThread extends Thread {
@Override
public void run() {
try {
while (true) {
if (++image == 4) {
image = 0;
}
Thread.sleep(100);
}
} catch (InterruptedException ex) {
}
}
}
}
W programie działają dwa wątki. Jeden to ten, który zmienia obrazek animowanego obiektu. Drugi to wątek główny, który pobiera od obiektu jego obrazek i rysuje go na panelu. Po uruchomieniu program działa jakiś czas po czym wyrzuca mi wyjątek "Array Index Out Of Bounds Exception".
Powodem jest to, że wątek zmieniający obrazek zostaje wywłaszczony przez wątek główny w chwili gdy jest on po inkrementacji zmiennej image, ale przed sprawdzeniem czy nie jest ona równa 4. W ten sposób metoda getImage() zwraca element o indeksie 4 z tablicy o rozmiarze 4. Oczywiście nie ma takiego elementu. Aby temu zapobiec postanowiłem wykorzystać synchronizację. Dotychczas próbowałem na dwa sposoby:
- Blok synchonizowany
synchronized (this) {
if (++image == 4) {
image = 0;
}
}
- Wywoływanie tego kodu z synchronizowanej metody
private class AnimationThread extends Thread {
@Override
public void run() {
try {
while (true) {
nextFrame();
Thread.sleep(100);
}
} catch (InterruptedException ex) {
}
}
private synchronized void nextFrame() {
if (++image == 4) {
image = 0;
}
}
}
Obie metody niestety nie działają i co jakiś czas dostaję ten wyjątek. Czy źle uzywam sychronizacji czy jest inny powód? Proszę o pomoc.