2013-10-03 7 views
3

Недавно я нашел пример кода:Почему важно использовать invokeLater?

public static void main(String[] args) { 
    javax.swing.SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGUI(); 
     } 
    }); 
} 

createAndShowGUI() метод открывает окно пользовательского интерфейса. Затем я попытался обрезать код следующим образом:

public static void main(String[] args) { 
    createAndShowGUI(); 
} 

Обе версии работают одинаково хорошо. В чем разница?

+1

Он работает одинаково хорошо, большую часть времени, но иногда ваш поток графического интерфейса и поток, обновляющий графический интерфейс, вызывают странное и невоспроизводимое поведение. Это проблема с тестированием многопоточного кода, вы можете запустить его в течение нескольких дней и изменить что-то незначительное, и внезапно оно появляется часто. –

+0

Возможный дубликат http://stackoverflow.com/questions/6567870/what-does-swingutilities-invokelater-do – Masudul

ответ

10

В 99% случаев любой код будет работать.

Однако Swing был разработан таким образом, что все обновления компонентов Swing должны быть выполнены в потоке отправки событий (EDT). Прочтите учебник Swing по телефону Concurrency для получения дополнительной информации.

Проблема 1% времени, когда она может не работать. Вы не хотите тратить время на попытки отладки случайных проблем.

4

SwingUtilities.invokeLater обеспечивает выполнение кода в потоке отправки событий (EDT). Swing является однопоточным, все экземпляры и отображение компонентов должны происходить на EDT. Возможно, что-то работает иначе, но вы, возможно, столкнетесь с проблемами.

3

Swing имеет однопоточную конструкцию на основе Event Loop и не является потокобезопасной, при этом только поточно-безопасная часть представляет собой набор методов invokeXXX(), используемых для передачи управления циклу событий Swing.

Ваш «сломанный» код работает просто отлично, потому что ничто другое не пытается коснуться одной и той же части структур данных Swing из цикла событий одновременно.

3

«Основная» нить, начатая JVM, не является Темами Диспетчер событий.

из The Event Dispatch Thread

Некоторые методы свинг компонентов помечены "Потокобезопасная" в спецификации API; они могут быть безопасно вызваны из любого потока. Все остальные методы компонента Swing должны быть вызваны из потока отправки событий. Программы, которые игнорируют это правило, могут нормально функционировать большую часть времени, но подвержены непредсказуемым ошибкам, которые трудно воспроизвести.