이벤트 디스패치 스레드

Event dispatching thread

Event Dispatching Thread(EDT; 이벤트디스패치스레드)는 Java에서 Abstract Window Toolkit(AWT) 그래피컬사용자 인터페이스이벤트 큐에서 이벤트를 처리하기 위해 사용되는 백그라운드스레드입니다는 이벤트 구동 프로그래밍의 일반적인 개념의 일례이며 웹 브라우저나 웹 서버Java 이외의 많은 컨텍스트에서 널리 사용되고 있습니다.

이벤트는 주로 사용자 인터페이스 컴포넌트가 자신을 다시 그릴 수 있는 업데이트이벤트 또는 마우스나 키보드 등의 입력 디바이스에서 이벤트를 입력합니다.AWT는 단일 스레드 도장 모델을 사용합니다.이 모델에서 모든 화면 갱신은 단일 스레드에서 수행해야 합니다.이벤트 디스패치스레드는 표시 가능한 사용자 인터페이스 컴포넌트의 비주얼 상태를 갱신할 수 있는 유일한 유효한 스레드입니다.다른 스레드에서 보이는 컴포넌트를 업데이트하는 것은 [1]Swing을 사용하는 Java 프로그램의 많은 일반적인 버그의 근원입니다.이벤트 디스패치 스레드는 Adobe Flash에서는 초기 작업자, SWT, .NET Framework 및 Android에서는 UI 스레드라고 불립니다.

GUI 접근을 시리얼화하기 위한 메시지루프

일반적으로 소프트웨어 애플리케이션은 여러 스레드와 단일 GUI 데이터 구조로 구성됩니다.즉, GUI는 공유 데이터 구조이며 한 번에 1개의 스레드만 액세스 할 수 있도록 하기 위해 동기화가 필요합니다.AWT Swing은 (스레드 안전하지 않은) 방식을 노출하여 GUI 컴포넌트를 만들고 GUI 컴포넌트에 액세스합니다.이러한 방식은 다른 GUI 프레임워크에서도 마찬가지로 모든 응용 프로그램스레드에 표시됩니다만, 이러한 [2][3][4]방식을 실행할 수 있는 것은 이벤트디스패치 스레드뿐입니다.프로그래머는 이 요건을 놓치는 경우가 많기 때문에 Substant와 같은 서드파티 Look and Feels는 Event Dispatch [5]Thread 내에서 실행되지 않을 때 Swing 컴포넌트의 인스턴스화를 거부하여 이러한 코딩 오류를 방지합니다.GUI에 대한 액세스는 시리얼화되어 다른 스레드는 EDT 메시지큐를 통해 EDT에서 실행되는 코드를 송신할 수 있습니다.

즉, 다른 GUI 프레임워크에서도 마찬가지로 Event Dispatching Thread는 메시지 펌핑에 소비합니다.GUI를 통해 실행되는 액션의 메시지큐를 유지합니다.이러한 요구는 시스템 및 응용 프로그램스레드에 의해 큐에 송신됩니다.EDT는 이들을 차례로 소비하고 GUI 컴포넌트를 갱신하여 응답합니다.메시지는 잘 알려진 액션이거나 EDT를 통해 실행해야 하는 사용자 메서드에 대한 참조인 콜백을 수반하는 경우가 있습니다.

모든 메시지에 부과되는 중요한 요건은 GUI가 응답성을 유지하려면 메시지를 신속하게 실행해야 한다는 것입니다.그렇지 않으면 메시지루프가 차단되고 GUI 프리즈가 발생합니다.

EDT에 사용자 코드 제출

EDT에 코드를 제출하고 루프를 차단하지 않고 장시간 작업을 수행하기 위한 다양한 솔루션이 있습니다.

컴포넌트 이벤트 핸들러(리슨)

GUI 컴포넌트는 일반적으로 컴포넌트 작성 시 입력되는 Listeners라고 불리는 콜백목록을 지원합니다.EDT는 사용자가 어떤 식으로든 컴포넌트를 들뜨게 했을 때 청취자를 실행합니다(버튼 클릭, 마우스 이동, 아이템 선택, 포커스 상실, 컴포넌트 크기 변경 등).

타이머

정기적으로 또는 특정 시간에 GUI에 액세스/변경해야 하는 짧은 태스크의 경우javax.swing.Timer사용됩니다.이 컴포넌트는 보이지 않는 GUI 컴포넌트로 간주할 수 있습니다.이 컴포넌트의 리스너는 특정 시간에 기동하도록 등록되어 있습니다.

등가물

  • System.Windows.Forms.Timer- .NET 프레임워크
  • flash.utils.Timer- Adobe Flash

다른 스레드로부터의 요구

다른 응용 프로그램스레드는 디스패치 시 실행할 코드를 다음 방법으로 전달할 수 있습니다.SwingUtilities도우미 클래스(또는EventQueueAWT를 하고 있는 경우).제출된 코드는 다음 기호로 둘러싸여 있어야 합니다.Runnable물건.이러한 클래스에는 다음 두 가지 방법이 있습니다.

이벤트 디스패치 스레드로부터.

방법invokeAndWait()이벤트 디스패치스레드에서 호출해서는 안 됩니다.예외가 느려집니다.방법SwingUtilities.isEventDispatchThread()또는EventQueue.isDispatchThread()를 호출하여 현재 스레드가 이벤트디스패치 스레드인지 여부를 판별할 수 있습니다.

에 의해 제공되는 코드invokeLater그리고.invokeAndWait가능한 한 빨리 EDT로 이동하여 결빙을 방지해야 합니다.통상, 장시간의 계산 결과를 GUI(사용자)에 전달하는 것을 목적으로 하고 있습니다.

작업자 설계 패턴

작업자 설계 패턴에 의해 다른 스레드에서의 작업 실행과 EDT에서의 결과 제시를 조합할 수 있다.javax.swing.SwingWorkerSun Microsystems에 의해 개발된 클래스는 워커 설계 패턴의 구현이며 Java 6에서는 표준 Swing 배포의 일부입니다.SwingWorker는 보통 EDT가 실행되는 이벤트 Listener에서 호출되며 EDT를 차단하지 않기 위해 긴 작업을 수행합니다.

샘플

Swing Worker(스윙 워커)< >문서, 무효> 작업자 = 신규 Swing Worker(스윙 워커)< >문서, 무효>() {     일반의 문서 doInbackground(배경)() 던지다 IOException(IOException) {         돌아가다 로드 XML(); // 부하가 높은 작업     }          일반의 무효 다 했어요.() {         해라 {             문서 문서 = 얻다();             표시(문서);         } 또 만나 (예외. ex) {             ex.print Stack Trace(프린트 스택 트레이스)();         }     } }; 작업자.실행하다(); 

그루비랑groovy.swing.SwingBuilder, 를 사용할 수 있습니다.doLater(),doOutside(),그리고.edt()그러면 다음과 같이 간단하게 쓸 수 있습니다.

외부 {     방어하다 문서 = 로드 XML() // 부하가 높은 작업     엣지 { 표시(문서) } } 

등가물

모달 실행

Swing Worker는 보통 콜백(Listener) 이벤트를 처리할 때 EDT에 의해 장시간 작업용으로 작성됩니다.작업자 스레드를 생성하면 EDT는 작업자의 완료를 기다리지 않고 현재 메시지 처리를 계속합니다.이것은 바람직하지 않은 경우가 많습니다.

대부분의 경우 EDT는 GUI 컴포넌트 액션을 처리합니다.이 액션은 팝업된 JFile Chooser와 같은 다른 대화 상자를 사용하여 사용자가 선택을 해야 하며 사용자가 해당 옵션을 선택하고 "OK" 버튼을 누른 후에만 선택한 파일에 대한 액션이 진행됩니다.이 작업에는 시간이 걸립니다(사용자가 몇 초 이내에 응답합니다).EDT가 블로킹되어 있는 동안에도 계속 응답하는 GUI(메시지는 EDT로 펌핑됩니다)가 필요합니다(예를 들어 JFileChooser, 대화상자가 닫히고 현재 컴포넌트 액션이 종료되기 전에 큐 내의 새로운 메시지는 처리되지 않습니다).이 악순환은 EDT가 새로운 메시지루프에 들어가면서 끊어집니다.EDT는 "모달대화상자"가 도착하고 컴포넌트 액션의 차단된 위치에서 일반 메시지 처리를 재개할 때까지 정상적으로 메시지를 디스패치합니다.

오픈 소스 Foxtrot 프로젝트는 Swing 메시지 루프 펌핑을 에뮬레이트하여 임의의 사용자 태스크에 "동기" 실행 메커니즘을 제공합니다.이것은 워커가 태스크를 완료한 후에만 진행됩니다.

  단추.add Action Listener(신규 액션 리스트너()   {   일반의 무효 실행한 액션(액션 이벤트 e)   {   단추.setText("잠자는 중....");    스트링 본문 = 무효;   해라   {      본문 = (스트링)작업자.포스트.(신규 작업()      {      일반의 물건 달려.() 던지다 예외.      {      .수면.(10000);      돌아가다 "잠들었다!";      }      });   }   또 만나 (예외. x) ...    단추.setText(본문);    뭔가 엘세();   }   }); 

Java 1.7 이후 Java는 시스템 EventQue()에서 createSecondaryLoop()을 공개함으로써 커스텀세컨더리 메시지루프를 위한 표준 솔루션을 제공합니다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ 이 문제는 Java Swing만의 문제는 아닙니다.대부분의 위젯 툴킷에서는 BackgroundWorker 클래스가 Java에서 SwingWorker와 동일한 목적을 수행하는 Windows Forms와 같은 문제가 발생합니다.
  2. ^ "The Event Dispatch Thread". Sun Microsystems. Retrieved 2011-10-02.
  3. ^ "Debugging Swing - is it really difficult?". Alexander Potochkin. Archived from the original on 2011-08-05. Retrieved 2011-10-02. {{cite web}}:외부 링크 publisher=(도움말)
  4. ^ "Initial Threads". Sun Microsystems. Retrieved 2011-10-02.
  5. ^ "Stricter checks on EDT violations in Substance · Pushing Pixels".

외부 링크