ユーザーインターフェイススレッド
しかし、データ共有するには、ロックをかけないといけないが、親コンポーネントから子コンポーネントを呼んだり、コールバックで子から親を呼んだり、アプリケーションからGUIライブラリを呼んだり、GUIライブラリからアプリケーションをコールバックしたりと、双方向に呼び出すことが多く、異なるスレッド間で双方向に呼び合うときは、ロックの順番に注意を払う必要がある。これはソフトウェアが非常に複雑になる原因となってしまう。また、ロック順序のミスが引き起こすデッドロックは常にではなくたまに発生したりすることの多いバグ(時間的確率要因が関与する偶発性のあるバグ)であり、バグ取りが大変になるという問題があった。
そこで、1997年のJavaのSwingからは、UIの操作は全てメインのUIスレッドであるイベントディスパッチスレッドから操作しなくてはならない、というルールを設けた。そして、2006年の Java 6 から、UIスレッドで重い処理をすることを避けるために、ワーカーデザインパターン(後述)を採用した javax.swing.SwingWorker を搭載した。
現在では、多くのUIライブラリが、UIスレッドに操作を限定することと、ワーカーデザインパターンの組み合わせを採用している。
GUIの描画に関しては、UIスレッドが実行するケースもあれば、UIスレッドとは別の専用レンダリングスレッドが実行するケースもある。
アプリケーションのメインスレッドは基本的にUIスレッドと同一・等価だが、特殊なケースとして、メインスレッドとUIスレッドが異なるケースもある。
System.ComponentModel.BackgroundWorker - .NET Framework
タスク並列ライブラリ(英語版) (TPL: Task Parallel Library) - .NET Framework
並列パターンライブラリ(英語版) (PPL: Parallel Patterns Library) - Visual C++/Windowsランタイム
flash.system.Worker - Adobe Flash
android.os.AsyncTask - Android
同一インスタンスのワーカーを2回以上実行したときに、それは、逐次処理するべきなのか、並列処理するべきなのかという議論があり、UIライブラリによって様々であるが、Androidにおいては、2009年9月のAndroid 1.6までは逐次処理、2009年11月のAndroid 2.