1

그래서 내가 본 수많은 다른 GUI 자습서, 그들 모두가이 코드를 사용할 말했다 :javax.swing.SwingUtilities.invokeLater가 아닌가요?

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

} 

을 내가 꽤 나는 GUI 다소 새로운 해요 이후이 정확히 무엇을 이해하지 수 있지만, 나는 그것이하는 일의 기초를 이해한다 ... 또는 그렇게 나는 생각했다. 그러나 실험으로, 나는 그것을 전부 버리고 방금 떠났습니다.

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

그리고 그것은 작동하는 것처럼 보였습니다. 이제 질문이 있습니다. 두 번째 코드를 사용하는 것보다 코드의 첫 번째 코드를 유지하는 목적은 무엇입니까? 필요하다면 사용하지 않으면 어떻게됩니까?

+1

'invokeLater()'는 필요시 안정적으로 동작하도록 만듭니다. 이것은 매번 발생하지 않는 스레딩 버그이지만 일반적으로 최악의 시간에 발생합니다. – user949300

+0

http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html을 참조하십시오. 코드가 작동하는 것처럼 보이는 이유는 스레드 경주가 재현하기가 어렵 기 때문입니다. 하지만 프로그램이 복잡해질수록 스레딩 규칙을 준수하지 않으면 스레드 버그 * 어딘가에 충돌 할 확률이 높아집니다. – kiheru

+0

언급했듯이 (그리고 다른 것들도 언급했듯이) 대부분의 경우에'invokeLater' * 없이는 작동하지 않을 것입니다. 그러나 나는 EDT에서 호출되지 않을 때 재현 가능한 * LookAndFeel을 사용했다는 것을 기억합니다. (이 경우 충돌은 API의 잘못된 사용이기 때문에 합법입니다.) – Marco13

답변

4

간단히 말해, API가 스레드 안전하다고하지 않는 한, Swing 객체를 변경할 때마다 필요합니다.

스윙 개체가 스레드로부터 안전하지 않으므로 GUI 변경 사항은 EDT (Event Dispatch Thread)에서 수행해야합니다. 처리 코드를 Event Dispatch Thread Tutorial

스윙 이벤트에서 이벤트 발송 쓰레드로 알려진 특별한 스레드에서 실행됩니다. Swing 메서드를 호출하는 대부분의 코드는 이 스레드에서 실행됩니다. 이것은 대부분의 Swing 객체 메소드가 "thread safe"가 아니기 때문에 이기 때문에 필요합니다. 다중 스레드에서 호출하면 스레드 간섭 또는 메모리 일관성 오류가 발생할 수 있습니다. 일부 Swing 구성 요소 메서드는 API 사양에서 "스레드 안전성"이라고 표시되어 있습니다. 이것들은 이 어떤 스레드에서든 안전하게 호출 될 수 있습니다. 다른 모든 Swing 구성 요소 메서드 은 이벤트 발송 스레드에서 호출해야합니다. 을 무시하는 프로그램은 대부분 올바르게 작동하지만 재현하기 어려운 예기치 않은 오류 의 영향을받을 수 있습니다.

SwingUtilities.invokeLater를 호출하면 실행 가능한 코드가 EDT에서 호출되고 이상한 오류가 발생하지 않습니다. 그래서 테스트 한 상황에서 아마 그랬기 때문에 코드를 제거하면 모든 것이 작동하는 것 같습니다. 그러나 항상 그런 것은 아니며 때로는 작동하거나 타이밍 문제가있는 코드를 원하지 않을 수 있습니다.