Jeśli narzędzia pobierające modele Swing nie są bezpieczne dla wątków, jak sobie z nimi radzisz?

Powszechnie wiadomo, że aktualizacja GUI Swing musi być przeprowadzana wyłącznie w EDT. Mniej reklamuje się toczytanie rzeczy z GUI muszą / powinny być również wykonane w EDT. Na przykład, weźmyButtonModel's isSelected () metoda, która informuje (na przykład) o stanie ToggleButton („w dół” lub „w górę”).

W każdym przykładzie, który widziałem,isSelected() jest swobodnie odpytywany z głównego lub dowolnego wątku. Ale kiedy patrzę na implementację DefaultButtonModel, nie jest zsynchronizowana, a wartość nie jest zmienna. Więc, ściśle mówiąc,isSelected() może zwrócić śmieci, jeśli jest odczytywane z dowolnego innego wątku niż ten, z którego jest ustawiony (czyli EDT, gdy użytkownik naciska przycisk). A może się mylę?

Początkowo myślałem o tym, gdy byłem zszokowany punktem # 66 w Efektywnej Javie Blocha, w tym przykładzie:

public class StopThread {
    private static boolean stopRequested;

    public static void main(String[] args) throws InterruptedException {
        Thread backgroundThread = new Thread(new Runnable() {
            public void run() {
                int i = 0;
                while(!stopRequested) i++;
            }
        });
        backgroundThread.start();

        TimeUnit.SECONDS.sleep(1);
        stopRequested = true;
    }
}

Wbrew pozorom ten program nigdy się nie kończy, przynajmniej na niektórych komputerach. AktualizowaniestopRequested flaga z głównego wątku jest niewidoczna dla wątku w tle. Sytuację można naprawić za pomocą zsynchronizowanych pobierających i ustawiających lub ustawiając flagęvolatile.

Więc:

Czy sprawdzanie stanu modelu Swing poza EDT (ściśle mówiąc) jest błędne?Jeśli nie, jak to się stało?Jeśli tak, jak sobie z tym poradzisz? Na szczęście, lub przez jakieś sprytne obejście? InvokeAndWait?

questionAnswers(6)

yourAnswerToTheQuestion