2011-11-15 12 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です。作業者を実装し、join()(およびstart())をdoInBackground()メソッドに入れます。その後、あなたがやりたいSwing操作はdone()に入ります。

+0

あなたは何を意味するのか説明できますか?私はあなたがUIスレッドをブロックすることによって何を意味するか分かりません。私はちょうどスレッドについて学び始めました。 –

+0

UIスレッド(またはEDT)は、UIイベント(マウスのクリックなど)の処理と画面の再描画を担当するスレッドです。 UIスレッドをブロックするということは、完了までに時間がかかる何かをすることを意味します。例えば ​​'join()'は、スレッドが「結合」スレッドが終了するまで待つ。これは比較的長い時間がかかる。ブロッキングの弊害は、その時間に他のUIイベントが処理されないことです。すなわち、UIが応答しなくなる。 (「長い時間」の長さは主観的ですが、あなたがそれを見たときにそれを知るでしょう) –

1

あなたはUIスレッドをブロックしています。あなたはそうしてはいけません。オプション:

  • ちょうど最初の3にjoinを呼び出し、別ののスレッドを持っています。別のリソースを作成するという点では無駄ですが、合理的に単純です。
  • メモリモデルと競合状態の問題が発生しないように、AtomicIntegerのようなものを使用してください。カウンタを3で開始し、各スレッドの最後にデクリメントします。最後のスレッドが処理を終了すると、カウンタが0になります。をUIにコールバックします。

(第2弾がそれだけの説明を与えられたことを確認するために伝えるのは難しいです...あなたはすでに何をしていたかもしれ「私はカウンターを使用していました。」)

私は完全にどこ」を参照しながらイベント駆動型の世界では、アプリケーションの制御フローが非常に難しくなってきており、スイングの仕組みです(他のほとんどのUIフレームワークでもそうです)。あなたは単にできません UIスレッドをブロックします。 (これは、C#5がの言語レベルですべてをより簡単にしている理由です)

+0

私は、どれくらいのスレッドが実行されたかを追跡するためにカウンタを使いました。すべてのスレッドが完了すると、私はdoSomething()を実行します。しかし、私はthread1.start()の後の次の行を望んでいます。 thread2.start()doSomething()。しかし、プログレスバーはすべて凍っています。 –

+0

@LewsTherin: 'SwingUtilities.invokeLater'を最後に終了したスレッドから' doSomething'を呼び出す必要があります。基本的には、UIスレッドで長時間実行することはできません。 –

+0

私はそれに感謝します。 –

関連する問題