- ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:イベントディスパッチングスレッドの振る舞いについて)
イベントディスパッチングスレッドの振る舞いについて
このQ&Aのポイント
- イベントディスパッチングスレッドを用いてコンポーネントに文字列を表示する処理が思った通りに動作しない理由について説明します。
- invokeLaterメソッドを使用して複数のイベントをイベントディスパッチングスレッドに格納し実行する場合、最後に格納されたイベントしか実行されず、途中のイベントは無視されます。
- この動作は、イベントキューに新しいイベントが追加されると、すでに実行中のイベントが完了するまで待機するためです。そのため、途中のイベントは実行される前に新しいイベントが追加され、無視されてしまいます。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
自信なし&カン --- たとえばLabel#setText()は イメージ的には setText(String text){ this.text=text;//…a repaint();//…b } となっているような気がします。 また、repaint()は イメージ的には repaint(){ //イベントキューに「再描画イベント」を入れる invokeLater(Event.UPDATE); } となっていると思います。 これがすべてだと思います。 --- さて、ここで setText()をS(注:Sはaとbから成る。上記参照), 「再描画イベント」をU と書くことにします。 そして (invokeLaterを使うなどして)イベントキューにSを3つ放り込んだとします。 するとキューの状態は SSS となります。(※左側がキューの先頭) やがてイベントスレッドで先頭のSが処理されます。 すなわち、まずaが処理され、次にbが処理されます。 bは「イベントキューへUを追加」にほかならないので、 この時点でのキューの状態は SSU となります。 ・ ・ と考えていくと、最後にはキューの状態は UUU となります。 --- この時点で、a(textの変更)は3度起こりましたが、 描画はまだ一度も起こっていません。
お礼
kacchann様へ ご回答ありがとうござした。 質問を投稿して以来いろいろ試してみたのですが、 kacchann様のご推測と同じような結論に至っておりました。 といいますのは、例えば、イベントディスパッチングスレッドによってinvokeLaterに、Runnableオブジェク トのrun()中にThread.sleep(1000)とsetText("newText"+i)を実装した ものを指定してinvokeLaterを10回実行させて10個のRunnable オブジェクトをイベントキューに格納させた ところ、確かに、イベントディスパッチングスレッドは個々のイベント を処理しているらしく、約10秒経過してからいきなりコンポーネント に「newText10」と表示が反映されました。また、 イベントディスパッチングスレッドによってinvokeLaterを実行させて イベントキューにRunnableオブジェクトを複数個格納させてから イベントディスパッチングスレッドにRunnableオブジェクトを処理 させると、質問のような現象が起きるのですが、もし他の任意の スレッド(例えばinvokerThreadと名づけましょうか)を作成してそのス レッドにRunnableオブジェクトを作成させてinvokeLaterを実行させると、イベントディスパッチングスレッドはinvokerThreadからの一つの Runnableオブジェクトだけを処理するだけでよいので、処理ごとに setText()の内容が反映されるようになりました。 つまり、イベントキューにイベントが「複数個」ある状態で、イベント ディスパッチングスレッドにキューのイベントを処理させると、質問の ような現象を起こし、イベントキューにイベントが「1つ」しかないと きはイベントディスパッチングスレッドは、イベントを処理後すぐに 処理内容がコンポーネントに反映されるようにするようです。