3秒でわかる
処理を一本の流れだけで順に実行していく方式のこと。競合が起きない代わりに、重い計算を挟むと画面ごと止まってしまう点に注意します。
もう少し詳しく
どういうものか
シングルスレッドは、プログラムが処理を一本の流れだけで順に実行する方式を指す。ある時点で動いているコードは常に 1 つで、次の処理はその完了を待つ。JavaScript は、ブラウザでも Node.js でも、利用者のコードを実行する部分がこの方式で動いている。
なぜ必要か
複数の流れが同時に同じ変数を書き換えると、実行の順番によって結果が変わる不具合が生まれる。この種の不具合は再現が難しく、原因の特定に時間がかかる。流れを一本に限れば、その心配が構造的に消える。DOM のように同時に触られると壊れる対象を扱う言語にとって、実装の単純さが利点になっている。
具体例
実行の流れは一本でも、時間のかかる処理は待たずに先へ進める。
console.log("1");
setTimeout(() => console.log("3"), 0); // 待ち行列へ回される
console.log("2");
// 出力は 1, 2, 3 の順になる一方で、重い計算を挟むと全体が止まる。
const t = Date.now();
while (Date.now() - t < 5000) {} // 5 秒間なにも受け付けないこの 5 秒間はクリックも画面の更新も処理されない。
つまずきやすいところ
「シングルスレッドだから同時に何もできない」と読むのは誤りになる。通信やファイル読み込みは実行環境の側で並行に進み、終わったものから待ち行列へ入る。一本なのは利用者のコードを実行する部分だけで、待ち時間そのものは重ならない。
止まる原因になるのは、待ちではなく計算になる。巨大な配列の総当たりや画像処理を素直に書くと画面が固まるため、Web Worker へ逃がすか、処理を分割して合間に制御を返す。Node.js のサーバーでは、同期版の readFileSync を要求ごとに呼ぶと、その間ほかの利用者の要求まで待たされる。
似た用語との違い
| 方式 | 実行の流れ | 主な注意点 |
|---|---|---|
| シングルスレッド | 1 本 | 重い処理で全体が止まる |
| マルチスレッド | 複数 | 共有データの排他制御が要る |
| マルチプロセス | 複数 (記憶領域も別) | 記憶領域の消費が大きい |
覚え方
窓口が 1 つの受付にあたる。書類を役所の奥へ回している間は次の人を呼べるが、窓口で長い計算を始めると行列が止まる。止まる原因は待ち時間ではなく、窓口を占有する作業のほうにある。
Node.js には worker_threads があり、重い計算だけを別の流れへ渡せる。既定が一本というだけで、必要なら分けられる。