ユーザーインターフェイススレッドとは? わかりやすく解説

Weblio 辞書 > 辞書・百科事典 > ウィキペディア小見出し辞書 > ユーザーインターフェイススレッドの意味・解説 

ユーザーインターフェイススレッド

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/02/09 17:12 UTC 版)

ナビゲーションに移動 検索に移動

ユーザーインターフェイススレッド (: user-interface thread) とは、アプリケーションソフトウェアグラフィカルユーザーインターフェイス (GUI) におけるメインスレッドのことを指す。UIスレッドと表記されることもある。本項では、GUIでのマルチスレッドに関するデザインパターンを記載する。ユーザーインターフェイススレッドは、JavaではイベントディスパッチスレッドAdobe Flashではprimordial workerと呼ばれる。

歴史的経緯

GUIアプリケーションにおいて、応答性を維持するためには、基本的にフレームの描画およびユーザー応答(さまざまなユーザー入力に対するアクション)はできるかぎり高いフレームレートで処理しないといけない[1]。例えば60fps (frames per second) の場合、1フレームの処理を1/60秒=約16ミリ秒以内に完了する必要がある。しかし、たとえどれほどプロセッサの性能が向上したとしても、I/O処理や画像・動画のデコード、通信接続の確立など、完了までに長時間かかってしまう処理は必ず存在する。そういったものを含めて、すべての処理を1つのスレッドだけで実行すると、長時間かかる処理を実行している間はフレーム描画やユーザー応答の処理ができないため、UIの反応がなくなってしまう(ハングアップ、フリーズ)[2]。長時間かかる処理の途中に、フレーム描画やユーザー応答に関わるメッセージ処理をときどき挟みながら、長時間かかる処理を少しずつ進める、という方法もあるが[3][4][5]、スマートでないうえに適用限界がある。応答性の低下を防ぐためにマルチスレッド化が必要だが、それをどのようにしてソフトウェアの構造設計に持ち込むか、ということに関して、歴史的には1980年代から色々と議論があった。

例えば、JavaAWTでは、1996年の最初の時点では、単純にスレッド間でデータ共有型のマルチスレッドになっていた。しかし、データ共有するには、ロックをかけないといけないが、親コンポーネントから子コンポーネントを呼んだり、コールバックで子から親を呼んだり、アプリケーションからGUIライブラリを呼んだり、GUIライブラリからアプリケーションをコールバックしたりと、双方向に呼び出すことが多く、異なるスレッド間で双方向に呼び合うときは、ロックの順番に注意を払う必要がある。これはソフトウェアが非常に複雑になる原因となってしまう。また、ロック順序のミスが引き起こすデッドロックは常にではなくたまに発生したりすることの多いバグ(時間的確率要因が関与する偶発性のあるバグ)であり、バグ取りが大変になるという問題があった[6]

そこで、1997年JavaSwingからは、UIの操作は全てメインのUIスレッドであるイベントディスパッチスレッドから操作しなくてはならない、というルールを設けた。そして、2006年の Java 6 から、UIスレッドで重い処理をすることを避けるために、ワーカーデザインパターン(後述)を採用した javax.swing.SwingWorker を搭載した。

現在[いつ?]では、多くのUIライブラリが、UIスレッドに操作を限定することと、ワーカーデザインパターンの組み合わせを採用している。

UIスレッドへの委譲

UIスレッドではないサブスレッドでの処理の進捗や完了を画面表示する場合などは、処理の途中でユーザーインターフェイス要素の操作が必要となる。そういった場面では、サブスレッドからUIスレッドに操作を依頼(委譲)することが、まず必要である。

Java

Javaの場合は、以下の方法で、UIスレッドに委譲できる。J2SE 1.3以降ではどちらもEventQueueのメソッドが呼び出される実装となっている。

同期処理は、処理が完了するまで待つ。

委譲される処理は、java.lang.Runnableインターフェイスrun()メソッドの実装として記述する。

他のライブラリ

.NETでは処理の委譲にデリゲートが使用されることが多い。

ワーカーデザインパターン

Java

javax.swing.SwingWorker を継承して、実装できる。A→B→Cと処理が進むとき、Bが重い処理とすると、Bを SwingWorker.doInBackground() で、Cを SwingWorker.done() で処理する。

実装例:

SwingWorker<Document, Void> worker = new SwingWorker<Document, Void>() {
    public Document doInBackground() throws IOException {
        return loadXML(); // 重い処理
    }
    
    public void done() {
        try {
            Document doc = get();
            display(doc);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
};
worker.execute();

doInBackgound() の戻り値を done() の SwingWorker.get() で取り出せる。done() はUIスレッドで動作するが、doInBackgound() はUIスレッドとは別のスレッドで動作する。上記例では、done() の中で読み込んだ XML の表示を行う。

Groovy

上記の例を Groovy で書く場合は、groovy.swing.SwingBuilder に doLater(), doOutside(), edt() があり、下記のようによりシンプルに書ける。

doOutside {
    def doc = loadXML() // 重い処理
    edt { display(doc) }
}

他のライブラリ

同一インスタンスのワーカーを2回以上実行したときに、それは、逐次処理するべきなのか、並列処理するべきなのかという議論があり、UIライブラリによって様々であるが、Androidにおいては、2009年9月のAndroid 1.6までは逐次処理、2009年11月のAndroid 2.0からは並列処理、2011年2月のAndroid 3.0からはデフォルトは逐次処理と、色々と変遷した[10]。並列処理にすると使うときにバグを生みやすくなると言うのが、逐次処理に戻した理由である。なお、ワーカー自体が逐次処理であっても、複数のワーカーインスタンスを作り、別々に実行すれば並列に処理できる。

Android 11以降はandroid.os.AsyncTaskは非推奨 (deprecated) となり、java.util.concurrentまたはKotlinコンカレンシーユーティリティの使用が推奨されている。

.NET言語では、TPLとコルーチンをバックエンドに利用した非同期処理の糖衣構文async/awaitも用意されている。async/awaitを使うことで、重い処理(I/Oのような完了時間が予測できない処理)はいったんサブスレッドに委譲しておき、その処理の完了を受けて後続処理を再開するようなコードを簡潔に記述できる。

タイマー

UIスレッドで呼び出されるタイマーも多くのライブラリで備わっている。

参照

  1. ^ 必要となるフレームレートは、アプリケーションの用途やモニターのリフレッシュレートなどの環境によっても異なる。VRでは120fpsなど、さらに高いフレームレートが要求される。
  2. ^ Preventing Hangs in Windows Applications - Win32 apps | Microsoft Docs
  3. ^ Idle Loop Processing | Microsoft Docs
  4. ^ DoEvents function (Visual Basic for Applications) | Microsoft Docs
  5. ^ Application.DoEvents Method (System.Windows.Forms) | Microsoft Docs
  6. ^ Multithreaded toolkits: A failed dream?
  7. ^ WinRTにおける同期版のCoreDispatcher.Invoke()メソッドはWindows 8プレビュー版で実装されていたものの、最終的に製品版では削除された。
  8. ^ Fixing CoreDispatcher.Invoke – How to Invoke Method in UI Thread in Windows 8 Release Preview - Mikael Koskinen
  9. ^ Looper.getMainLooper()で得たLooperを使って作成したHandlerpost(Runnable)などを利用することもできる。
  10. ^ AsyncTask | Android Developers

外部リンク


ユーザーインターフェイススレッド

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/06/16 09:55 UTC 版)

スレッド (コンピュータ)」の記事における「ユーザーインターフェイススレッド」の解説

詳細は「ユーザーインターフェイススレッド」を参照 グラフィカルユーザインタフェースにおいてはデッドロックまつわる複雑さ回避するためUI操作するスレッド1つ統一しその上でワーカーデザインパターンを採用するという手法がよく採用される

※この「ユーザーインターフェイススレッド」の解説は、「スレッド (コンピュータ)」の解説の一部です。
「ユーザーインターフェイススレッド」を含む「スレッド (コンピュータ)」の記事については、「スレッド (コンピュータ)」の概要を参照ください。

ウィキペディア小見出し辞書の「ユーザーインターフェイススレッド」の項目はプログラムで機械的に意味や本文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。 お問い合わせ


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「ユーザーインターフェイススレッド」の関連用語

ユーザーインターフェイススレッドのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



ユーザーインターフェイススレッドのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのユーザーインターフェイススレッド (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。
ウィキペディアウィキペディア
Text is available under GNU Free Documentation License (GFDL).
Weblio辞書に掲載されている「ウィキペディア小見出し辞書」の記事は、Wikipediaのスレッド (コンピュータ) (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。

©2025 GRAS Group, Inc.RSS