2011-11-15 6 views
1

스레드를 사용하여 여러 진행률 표시 줄을 실행하는 코드가 있습니다.Thread.join은 진행률 표시 줄을 고정합니다.

Thread thread1 = new Thread(progressbar1); 
thread1.start(); 
thread2.start() 

등등. 내가 가진 후

thread1.join(); 
thread2.join(); 
thread3.join(); 

그러나 3 개의 진행률 표시 줄 애니메이션이 모두 정지되고 모든 스레드가 완료 될 때만 완료를 보여줍니다. 이 문제를 해결하는 방법? 감사합니다. .

+0

[초기 스레드] (http://download.oracle.com/javase/tutorial/uiswing/concurrency/) initial.html). – trashgod

답변

3

Event Dispatch Thread에서 차단 작업을 수행하면 GUI가 응답하지 않게되고 다시 그리기가 중단됩니다. 이것이 장기 실행 작업이 백그라운드 스레드에서 수행되어야하는 이유입니다.

백그라운드 스레드에서 일을해야하지만 EDT를 차단해야한다는 것을 알 것 같습니다. 너는 그렇게해서는 안된다. 대신 콜백이 필요합니다. 백그라운드 코드가 실행되면 코드가 실행됩니다.

Java 6 이상에서 이미 제공되는 콜백 메커니즘은 SwingWorker입니다. 작업자를 구현하여 doInBackground() 메서드에 join() (및 start() 초)을 넣습니다. 이후에 수행하고 싶은 Swing 연산은 done()으로 갈 수 있습니다.

+0

무슨 뜻인지 설명해 주시겠습니까? 내가 UI 스레드를 차단하여 무슨 뜻인지 모르겠다. 방금 스레드에 대해 배우기 시작했습니다. –

+0

UI 스레드 (또는 EDT)는 UI 이벤트 (예 : 마우스 클릭)를 처리하고 화면을 다시 그려주는 스레드입니다. UI 스레드를 차단하는 것은 완료하는 데 오랜 시간이 걸리는 작업을 수행하는 것을 의미합니다. 예를 들어'join()'은 "joined"쓰레드가 종료 될 때까지 쓰레드를 기다리게하고 ... 상대적으로 오랜 시간이 걸릴 수있다. 블로킹의 위험은 그 시간 동안 다른 UI 이벤트가 처리되지 않는다는 것입니다. 즉, UI가 응답하지 않게됩니다. ("오랜 시간"의 길이는 주관적이지만, 당신이 그것을 보았을 때 알 수 있습니다.) –

1

UI 스레드를 차단하고 있습니다. 너는 그렇게해서는 안된다. 옵션 :

  • 단지 처음 세에 join를 호출하는 다른 스레드를 가지고. 다른 리소스를 만드는 측면에서 낭비이지만 합리적으로 간단합니다.
  • 메모리 모델 및 경쟁 조건 문제가 발생하지 않도록하려면 AtomicInteger과 같은 것을 사용하십시오. 카운터를 3에서 시작하고 각 스레드의 끝에서 감소시킵니다. 마지막 스레드가 작업을 마쳤을 때 (즉, 감소가 카운터를 0으로 만들 때) 을 UI로 다시 호출합니다.

(두 번째 총알은 이미 무엇을하고 있는지 될 수있다 ... 그것은 확실히 단지의 설명을 주어 말할 어렵다 "나는 카운터를 사용했습니다.")

내가 완전히 볼 수 있지만 어디 ' 이벤트 중심의 세계에서 응용 프로그램의 제어 흐름이 훨씬 어려워지면 Swing이 작동합니다 (다른 대부분의 UI 프레임 워크가 작동하는 방식이기도합니다). 단순히 UI 스레드를 차단할 수 없습니다. (C# 5가 언어의 레벨에서 모든 것을 더 쉽게 만들어주는 이유이기도합니다.)

+0

나는 얼마나 많은 쓰레드가 수행되었는지를 추적하기 위해 카운터를 사용했습니다. 모든 스레드가 완료되면 나는 doSomething()을 수행한다.하지만 thread1.start(); 다음 줄을 원한다. thread2.start() doSomething(). 하지만 진행 표시 줄이 모두 고정되어 있습니다. –

+0

@LewsTherin : 스레드가 마침내'doSomething'을 호출하는 스레드에서 SwingUtilities.invokeLater를 사용해야합니다. 기본적으로 UI 스레드에서 오랫동안 실행되는 것은 할 수 없습니다. –

+0

감사합니다. –

관련 문제