ジョンは本当の要点を説明しませんでした。
JavaはスレッドExecutorService
に基づいていますが、C#はファイバーに基づいていると言えます。await
どちらもマルチタスクを可能にし、コンピューティング リソースを並行機能 (つまり、「同時に」実行される機能) に分割します。マルチタスクの最初の種類はプリエンプティブと呼ばれ、2 番目のマルチタスクは協調的と呼ばれます。歴史的に、プリエンプティブ マルチタスキングは協調的よりも高度で優れていると考えられていました。実際、プリエンプティブ マルチタスキングが消費者向けオペレーティング システムでサポートされるようになる前は、コンピューターは本当に最悪でした。ただし、プリエンプティブ マルチタスクには欠点があります。プログラミングが難しくなる可能性があり、より多くのメモリを使用します。
この 2 つの主な違いは、プリエンプティブ マルチタスキングにより、ランタイム (通常はオペレーティング システム自体) が任意の機能をいつでも停止し、別の機能を開始できる (そしてそれらを異なる CPU で同時に実行できる) ことです。一方、協調的なマルチタスクでは、実行中の機能を終了するか、自発的に一時停止する必要があります。私たちのほとんどは、マルチスレッドの形でのプリエンプティブ マルチタスクと、それに伴う慎重なプログラミングに精通しています。現在、ファイバーまたはコルーチンと呼ばれることが多い協調マルチタスクに精通している人はほとんどいません (この場合、プリエンプティブ OS のスレッド内のユーザーランドに実装されます)。
とにかく、要点は、ExecutorService
とawait
は直接比較できるものでawait
はなく、一般に、実際のマルチスレッドよりも優れているわけではありません (優れたシンタックス シュガーを備えていることを除けば)。C# を含めるawait
(そしてそれを協調マルチタスクに基づく) 理由は、プラットフォーム上の主要な GUI ツールキットがマルチスレッド用に設計されておらず、並行性をサポートするためにそれらをリファクタリングするのに大量の作業が必要になるためです。ほとんどのイベント ハンドラーは短く、連続して実行できるため、協調マルチタスクは UI に適しています。await
長いイベント ハンドラーが一時停止し、レンダリング関数が実行される機会を得た後に再開できるようにすることで、イベント ループの概念を拡張します。これらはすべて、1 つの CPU コアの 1 つのスレッドで発生します。
両者の共通点は、どちらもマルチタスクの形式であり、Future.get
両方await Task
とも同期の形式であるということです。
当然のことながら、C# にはスレッドとスレッド プールの適切なサポートがないわけではありません。同様に、Java には、Servlet 3.0 やjavafx.concurrent.Task
.
Jon Skeet への回答:継続(ファイバーのユーザーランド実装メカニズムが呼び出されるため) は自明ではありませんが、スレッドの実装はそれほど洗練されていません。スレッドの背後にあるアルゴリズムは、コンパイラや .NET ランタイムではなく OS にあるため、Jon は見捨てられた可能性があります。