Mam pętlę while działającą w mojej głównej metodzie programu Java. Pętla ma działać, dopóki zmienna flagi boolowskiej nie zostanie ustawiona na true w metodzie keyPressed programu (dodałem program jako KeyListener do JFrame).Podczas gdy pętla nie kończy się po zmianie flagi w innym wątku
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class ThreadWhile implements KeyListener {
private boolean flag = false;
public static void main(String[] args) {
//Set up key listening on a dummy JFrame
JFrame frame = new JFrame("Key Detector 9000");
frame.setVisible(true);
ThreadWhile tw = new ThreadWhile();
frame.addKeyListener(tw);
System.out.println("Looping until flag becomes true...");
while(!tw.flag) {
//Commenting the println out makes the loop run forever!
System.out.println(tw.flag);
}
System.out.println("Flag is true, so loop terminated.");
System.exit(0);
}
public void keyPressed(KeyEvent e) {
flag = true;
System.out.println("flag: " + flag);
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
To jest moje zrozumienie, że keyPressed metody wykonać we własnych wątków, więc wydaje się, kiedy uderzę klucza, zmienna „flaga” powinna być ustawiona na wartość true, a pętla przy uruchomionej w głównej metody powinien się skończyć.
JEDNAK, kiedy uruchamiam ten program, pętla działa wiecznie, nawet jeśli widzimy, że zmienna 'flag' jest ustawiona prawidłowo! Co dziwne, program zachowuje się poprawnie, jeśli wstawię szybkie echo System.out.println zmiennej 'flag' wewnątrz pętli while, ale oczywiście nie chcę niczego drukować w pętli.
Zgaduję, że ten problem może być wynikiem kompilatora Java, który próbuje zoptymalizować pustą pętlę while do punktu, w którym przestaje sprawdzać zmienną "flag"? Czy ktoś ma sugestie, aby to działało poprawnie, lub może bardziej sprytne podejście oparte na współbieżności, aby główny wątek wstrzymał się, dopóki wątek keyPressed nie zostanie wykonany?
Dzięki!
Stosować strzeżone bloki zamiast (http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html). Zapętlenie i oczekiwanie, że coś się spełni, zepsuje wydajność aplikacji i sprawi, że przestanie reagować. –