TOP設計・移行・活用> ウェイト中のスレッドを再開するときはnotifyAll()メソッドを利用する(C_TRD002)
Javaコーディング規約
Javaコーディング規約

第12回:スレッド・ガベージコレクションに関するコーディング規約
著者: 電通国際情報サービス  高安 厚思、東田 健宏
アイエックス・ナレッジ  河野 弥恵   2006/1/25
前のページ  1  2   3  4  次のページ
ウェイト中のスレッドを再開するときはnotifyAll()メソッドを利用する(C_TRD002)

   ウェイト中のスレッドが複数ある場合、スレッドの再開にnotify()メソッドを使わないでください。

   norify()メソッドはスレッドをどれか1つだけ再開します。しかしどのスレッドが再開されるか特定できないため、ウェイトが掛かったまま再開されないスレッドができる危険性があります。

   改札口モデルでいえば、待合室にいる乗降客を無作為に1人だけ外に連れ出すため、待合室に入ったままずっとでてこられなくなる乗降客が発生する可能性があります。

   notifyAll()を使用すれば、「すべてのスレッドが再開される=待合室にいる全員が外にだされる」ことになるためその危険を回避することができます。


Threadクラスのyield()メソッドは利用しない(C_TRD003)

   yield()はスレッドの切り替えを促すメソッドですが、「JavaVM」によって動作が異なるため、動作の保障ができません。

   スレッドの切り替えには、wait()メソッドを利用してください。


synchronizedブロックからsynchronizedブロックのあるメソッドを呼び出さない(C_TRD004)

   synchronizedブロックからsynchronizedブロックのあるメソッドを呼び出すと、デッドロックを起す可能性があります。例えば、改札口を2つ繋げた様子をイメージしてください。

改札口の例
図5:改札口の例

   synchronizedブロック"A"からsynchronizedブロック"B"が呼び出される仕組みは、改札Aと改札Bが繋がっている様子とよく似ています。

   改札Aを通った客は、改札Bも続けて通らないと外へでられません。しかし、この繋がった改札口を逆からも通れるとしたらどうでしょうか。

   改札Aを通った客は続けて改札Bを通ろうとしますが、改札Bには逆から入ってきた客がいるために通り抜けができません。また、改札Bを通った客は改札Aの客がいなくなるまで改札Bの中で待ち続けます。2人の客は、お互いに待ち続けたまま動くことができなくなります。

   これがデッドロックです。

   時には、synchronizedブロックからsynchronizedブロックのあるメソッドを呼び出す必要性もあるかも知れません。その場合は、デッドロックを起こさないように十分気をつけてください。


wait()、notify()、notifyAll()メソッドは、synchronized ブロック内から利用する(C_TRD006)

   wait()メソッド、notify()メソッド、notifyAll()メソッドの3つはスレッドクラスのメソッドではなく、オブジェクトクラスのメソッドです。そのため「syncronizedブロック=同期化された処理」の存在に関わらずコーディングをすることができますが、同期化された処理の外でこれらのメソッドを使うと例外が発生します。

   では、改札口モデルで考えてみましょう。

   「改札口を通る乗降客を制止して待合室へ連れて行く」「待合室から乗降客を連れ出す」という行為は、乗降客(スレッド)の動作ではなく、改札口(同期化された処理)を管理する駅員の動作といえます。

   駅員は駅舎の入口を通っただけの乗降客を「制止して待合室へ連れて行く」ことも可能です。しかし、駅舎の入口を通っただけの乗降客をいきなり待合室へ連れて行ったらクレームを受けてしまうでしょう。

   ちなみに駅舎の入口を通ることは「同期化されていない処理=syncronizedブロックの外」であり、複数のスレッドがいくつでも同時に処理できるため、wait()メソッドを使う必要がありません。syncronizedブロックの外でwait()メソッドを使おうとすると、java.lang.illegalMonitorStateExceptionが発生します。

前のページ  1  2   3  4  次のページ


株式会社電通国際情報サービス 開発技術センター 高安 厚思
著者プロフィール
株式会社電通国際情報サービス  高安 厚思
株式会社電通国際情報サービス 開発技術センター
Java(J2EE)/オブジェクト指向の研究開発やプロジェクト支援、開発コンサルティングに従事。モデル、アーキテクチャ、プロセスが探求対象。今回は Javaコーディング規約2004の仕掛け人。


株式会社電通国際情報サービス 開発技術センター 東田 健宏
著者プロフィール
株式会社電通国際情報サービス  東田 健宏
株式会社電通国際情報サービス 開発技術センター
CTI、Webアプリの開発経験を経て、現在は主にプロジェクトマネジメント支援、プロセスエンジニアリング、ソフトウェア工学研究開発に従事。最近はコーチング、ファシリテーションといったヒューマン系スキルに興味を持ち日々修得に努めている。


アイエックス・ナレッジ株式会社 河野 弥恵
著者プロフィール
アイエックス・ナレッジ株式会社  河野 弥恵
アイエックス・ナレッジ株式会社 第1事業部所属
主にCOBOL、PL/1等のシステム開発に従事。コーディングに限らず、誰もが気持ちよく守れる規約を模索中。


INDEX
第12回:スレッド・ガベージコレクションに関するコーディング規約
  はじめに
ウェイト中のスレッドを再開するときはnotifyAll()メソッドを利用する(C_TRD002)
  wait()メソッドはwhileブロック内から利用する(C_TRD007)
  その他