자바 GUI 프로그래밍, GUI는 왜 단일스레드일까?

자바 GUI 프로그래밍, GUI는 왜 단일스레드일까?


예전에는 자바 GUI 애플리케이션이 단일 스레드로 동작했으며, 자바 GUI 이벤트는 애플리케이션의 메인 이벤트 반복문main event loop에서 처리했었다.


하지만 최근에 등장한 GUI 프레임웍은 약간 다른 구조로 만들어져 있는데, 이를테면 이벤트 처리 스레드 EDT, event dispatch thread에서 자바 GUI 이벤트를 전담해서 처리하게 돼 있다.


Qt GUI 프로그래밍[자바 GUI 프로그래밍, GUI는 왜 단일스레드일까?]


자바에서만 GUI 프레임웍을 단일 스레드로 구성한 것은 아니다.


Qt, 넥스트스텝NextStep, Mac OS의 코코아Cocoa, X윈도우 등을 포함한 대부분의 자바 GUI 프레임웍이 단일 스레드로 동작하게 돼 있다. 그렇다고 해서 아무도 단일 스레드를 벗어나려고 시도하지 않았던 것은 아니다. GUI 프레임웍에서 여러 개의 스레드를 사용하고자 하는 시도는 많았지만, 대부분 경쟁 조건race condition과 데드락deadlock 등의 문제가 계속해서 발생했다.


결국, 대부분의 프레임웍이 이벤트 처리용 전담 스레드를 만들고, 전담 스레드는 큐에 쌓여 있는 이벤트를 가져와 애플리케이션에 준비된 이벤트 처리 메소드를 호출해 기능을 동작시키는 단일 스레드 이벤트 큐 모델에 정착한 셈이다


AWT는 멀티스레드에서 훨씬 자유롭게 활용할 수 있도록 구성돼 있었지만, 스윙을 설계할 때에는 AWT에서의 경험을 살려 여러 단점을 없앨 수 있도록 단일 스레드로 만들었다.


멀티스레드로 구현된 자바 GUI 프레임웍은 특히나 데드락 상황에 빠지기 쉬울 수밖에 없는데, 입력된 이벤트를 처리하는 과정과 GUI 컴포넌트를 구성한 객체 지향적인 구조가 어긋나는 경우가 많기 때문이다. 사용자가 취한 행동은 항상 운영체제에서 해당 애플리케이션으로 한 단계씩 넘어오게 돼 있다.


예를 들어 사용자가 마우스를 클릭하면 먼저 운영체제의 자바 GUI 프레임웍에서 클릭 이벤트를 생성하고, 해당 애플리케이션의 이벤트 리스너에게 "버튼을 눌렀다"는 등의 이벤트를 넘겨준다.


자바 스윙 예제[자바 GUI 프로그래밍, GUI는 왜 단일스레드일까?]


반대로 애플리케이션에서 시작된 동작은 운영체제에게 한 단계씩 넘어간다.


예를 들어 특정 컴포넌트의 배경 색을 변경하는 동작이라면, 먼저 애플리케이션에서 동작을 취하고, 그 동작이 해당 컴포넌트를 거쳐 결국 운영체제로 넘어가 색을 칠하게 된다.


GUI 애플리케이션의 작업은 대부분이 이처럼 하나의 자바 GUI 컴포넌트를 놓고 양방향으로 움직이는 과정을 거치게 돼 있는데 이 과정에 속한 객체가 스레드 안전하도록 동기화시키다 보니 락이 배치되는 순서가 적절하지 않은 경우가 많아진다.


이처럼 락이 잘못된 순서와 구조로 배치되면 데드락에 걸릴 수밖에 없다. 이런 증상과 그 원인은 대부분의 GUI 프레임웍을 개발하는 과정에서 경험적으로 깨닫게 됐다. 멀티스레드를 사용하는 GUI 프레임웍에서 데드락이 발생하는 또 다른 이유 가운데 하나는 바로 최근 널리 사용하는 MVC model-view-controller 패턴이다.


사용자 인터페이스를 모델, 뷰, 컨트롤러 객체가 협업하면서 움직이는 구조로 나누면 자바 GUI 애플리케이션을 구현하는 단계는 굉장히 간편하게 작업할 수 있지만, 락의 순서가 올바르지 않게 배치될 가능성이 크다.


컨트롤러는 모델 내부의 값을 불러다 사용하고, 변경된 내용은 뷰를 통해 화면에 표시한다.


자바 GUI 단일 스레드[자바 GUI 프로그래밍, GUI는 왜 단일스레드일까?]


반대로 컨트롤러에서 뷰의 기능을 호출하면서 모델 내부의 상태를 확인하기 위해 모델의 기능을 호출하기도 한다.

그러다 보니 객체마다 락이 걸리는 순서가 잘못 맞물려 데드락에 걸릴 가능성이 크다.


자바 GUI 프로그래밍[자바 GUI 프로그래밍, GUI는 왜 단일스레드일까?]


썬마이크로시스템즈의 부사장인 그레이임 해밀턴Graham Hamilton은 자신의 블로에 멀티스레드 GUI 프레임웍이 컴퓨터 과학 역사상 여러 가지 "이룰 수 없는 꿈" 가운데 하나라고 설명하고 있다.


멀티스레드 자바 GUI 프레임웍을 사용하더라도 다음과 같은 조건이 만족한다면 프로그램을 제대로 작성할 수 있다.


1. 일단 GUI 프레임웍이 굉장히 세심하게 설계돼 있어야 하고,

2. 내부적인 락과 동기화 방법을 아주 사소한 부분까지 공개해야 하고,

3. 개발자가 굉장히 똑똑하면서 주의 깊은 사람이어야 하고,

4. 그 개발자가 GUI 프레임웍의 내부 구조에 대해서 처음부터 끝까지 꿰뚫고 있어야 한다.


위에서 언급한 여러 가지 조건 가운데 하나라도 약간 틀어진다면 프로그램이 대충 동작하는 것처럼 보이겠지만, 데드락 때문에 프로그램이 종종 멈추거나 경쟁 상황 때문에 여러 문제가 생길 것이다.


멀티스레드를 사용하는 방법은 GUI 프레임웍을 설계하는 일에 직접 참여했던 개발자만이 제대로 활용할 수 있을 것이다.


자바 프로그래머, 프로그래밍[자바 GUI 프로그래밍, GUI는 왜 단일스레드일까?]


불뱅한 일이지만 멀티스레드 자바 GUI 프레임웍의 이런 특성을 보면 상용 애플리케이션에 널리 사용되지 못할 것이 분명하다.


똑똑한 개발자를 데려다 애플리케이션을 만들고 나면 결국에는 원인도 제대로 찾을 수 없는 이상한 오류가 발생하면서 불안정하게 동작하는 결과를 얻을 가능성이 크다.


그러면 개발자가 기분만 상하고 오류가 발생하지 않을까 겁을 내게 되는 데다 괜한 GUI 프레임웍에 대고 욕이나 하게 될 것이다.


단일 스레드 GUI 프레임웍은 스레드 제한 기법으로 스레드 안전성을 보장한다. 화면 컴포넌트나 데이터 모델과 같은 모든 자바 GUI 객체는 항상 이벤트 스레드에서 독점적으로 사용한다.


물론 이런 구조로 동작하다 보니 애플리케이션을 작성하는 개발자는 각종 객체가 이벤트 스레드에 적절하게 제한돼 동작하도록 만들어야 하는 부담을 가질 수밖에 없다.


자바 GUI 프로그래밍, GUI는 왜 단일스레드일까?

이 글을 공유하기

댓글(0)

Designed by JB FACTORY