Revised: Mar./23rd/2002
デッドロックとは、複数のスレッドがお互いをブロックすることで、処理が停止してしまうことです。狭義には、複数のスレッドがモニターのロックの解放を同時に待つことで処理が停止することです。
同期は他の制御との協調ですから、お互いににらみ合って制御が進まないことも起こりえます。マルチプロセス/マルチスレッドの話題では、必ず問題になる現象です。
あるスレッドが A と B を扱って、 A を処理する為に B を必要だとします。一方、別のスレッドでは B を処理しており、そのために A が必要であったとします。このとき、同期のタイミングによっては、二つのスレッドがお互いに相手の処理が終了して自分がロック取得できるようになるのを待機してにらみ合ってしまうことがあります。このようなときには幾ら待ってもそれ以上処理は進みません。これがデッドロックです。
Java ではデッドロックの発生を検出したり解消したりする仕組みは提供されていません。設計/開発する側がロジックで注意する必要があります。
A と B の両方のロックの取得が必要な処理の場合は、二つのモニターに対して平行してロック取得した方が処理は早く進みますが、上で挙げたようにデッドロックの危険があります。処理効率は落ちますが、シーケンシャルに A のロック取得の成功を、 B のロック取得の条件にすればデッドロックは防げます。
或いは、デッドロックの危険を考慮して、スレッドの待機を一定時間に制限することも考えられます。ロックを取得できずに特定の処理が実行できなくても、強制的に次の制御に進めてしまうわけです。これを一般にタイムアウトと呼びます。
デッドロックに似た現象でスローダウンということも起こります。デッドロックは処理が停止してしまいますが、スローダウンはスループットが著しく減退することであり、CPUやメモリーなどマシンリソースが大量に消費されることで発生します。たとえば、ネットワーク環境で送信したパケットの応答待ちで、メモリ領域を占有するジョブが大量にたまるとスローダウンが発生し、タイムアウトせずに放っておくと最悪の場合システムダウンに追い込まれます。