Известно, что обновление GUI Swing должно выполняться исключительно в EDT. Меньше рекламируется, что , читающий материал из GUI должен/должен также быть выполнен в EDT. Например, давайте возьмем метод ButtonModel's isSelected(), который сообщает (например) состояние ToggleButton («вниз» или «вверх»).Если ростеры моделей Swing не являются потокобезопасными, как вы справляетесь с ними?
В каждом примере, который я видел, isSelected()
свободен от основной или любой другой темы. Но когда я смотрю на реализацию DefaultButtonModel, она не синхронизируется, и значение не является изменчивым. Так, строго говоря, isSelected()
может возвращать мусор, если он читается из любого другого потока, кроме того, из которого он установлен (который является EDT, когда пользователь нажимает кнопку). Или я ошибаюсь?
Первоначально я думал об этом, когда в шоке от пункта # 66 в Блоха Эффективное Java, этот пример:
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;
}
}
Вопреки тому, что это, кажется, что программа никогда не заканчивается, на некоторых машинах, по крайней мере. Обновление флага stopRequested
из основного потока невидимо для фонового потока. Ситуацию можно исправить с помощью синхронизированных геттеров &, или установив флаг volatile
.
Итак:
- запрашивает состояние качелей модели вне EDT (строго говоря) не так?
- Если нет, то почему?
- Если да, то как вы справляетесь с этим? К счастью, или каким-то умным обходным решением? InvokeAndWait?
+1 для приятного подробного объяснения. –
Я должен был бы не согласиться с №1, потому что это вводит в заблуждение новичков. Им следует изучить правило «доступ к качелям вне EDT - это не-нет» и только после того, как они полностью поймут, почему они должны нарушать правила. Новичок только увидит ваши первые три слова «Нет, не ошибаюсь ...». Не говоря уже о том, что потоковая передача достаточно сложна, так как она не беспокоится о том, правильно ли вы синхронизируете свою модель. Единственная причина, по которой я вас не проголосовал, - это то, что ваш раздел Caveat - это правильный способ справиться с этим. – Nemi
Приношу свои извинения за то, что вы назвали Joonas «новичком». :) – Nemi