みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

スレッドの待機と再開

お世話になります。

マルチスレッドのプログラムで悩んでいます。

public class ThreadLocker {
 private static boolean isLocked = false;
 
 public static void lock() {
  isLocked = true;
  while(isLocked) { ; }
 }
 
 public static void unlock() {
  isLocked = false;
 }
}

まず、このようなクラスを定義しました。そして複数のスレッドが ThreadLocker.lock(); を呼び出して、処理の進行をストップしている状態があるとします。この状態に対して、とある別のスレッドが ThreadLocker.unlock(); を呼び出すと、それまで無限ループしていたスレッドが解放されて処理を始める、という感じです。

この方法を試してみましたが、無限ループで何も処理をしていないとは言え、リソースを食いまくっているようで、マシンが重くなってしまいました。

そこで、スレッドの待機・再開を行う事ができる wait / notify(All?) メソッドを使用すれば良いのではないかと考えたのですが、具体的な方法が分からず、質問させていただきました。

具体的に、どのインスタンスの wait 及び notify(All?) を呼び出せば良いのかが分かりません。
APIリファレンスの「現在のスレッドはこのオブジェクトのモニターのオーナでなければなりません。」の意味もよく分かりません。
ちなみに、待機しているスレッドは複数あり、class Lock の method execute 中で ThreadLocker.lock() しているとします。
また、再開を促すスレッドは1つで、class Unlock の method execute 中で ThreadLocker.unlock() を呼び出すものとします。
そして、それぞれのスレッドは、お互いのインスタンスを知りません。(説明しづらいので、補足要求があれば、ソースで示します。)

よろしくお願いいたします。

投稿日時 - 2007-01-26 23:34:44

QNo.2699029

すぐに回答ほしいです

質問者が選んだベストアンサー

参考URLの記事などを一通りお読みになった上で
わからない点を再度ご質問されるのがよろしいかと
思われます。

wait()は対象のオブジェクトに対して呼び出すので、
どこで呼んでもも構いませんが、対象のオブジェクトの
ロックをsynchronizedなどで獲得しておく必要が
あります。

参考URL:http://www.javaworld.jp/technology_and_programming/-/10941-1.html

投稿日時 - 2007-01-27 01:06:07

お礼

御礼が遅くなりまして、失礼いたしました。
参考URLを読ませていただき、以下のようなコードで対処することにいたしました。

public class ThreadLocker {
 private static Object obj = new Object();
 
 public static void lock() {
  synchronized (obj) {
   try {
    obj.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
 
 public static void unlock() {
  synchronized (obj) {
   obj.notifyAll();
  }
 }
}

どうもありがとうございました。

投稿日時 - 2007-01-31 03:01:49

ANo.1

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

> この方法を試してみましたが、無限ループで何も処理をしていないとは言え、リソースを食いまくっているようで、マシンが重くなってしまいました。

このような状態をBUSY-WAITといいます。なにも処理していないつもりでも、スレッドコンテキストの切り替えと、ループ処理と、CPUによってはキャッシュから主記憶への書き戻しなどを繰り返し行っています。

オブジェクトの同期で回避されるということですが、やりたいことがイベントの発生を待っているのか?単に排他したいだけなのか?あるいは、通知後に複数いるスレッドのうち、どのスレッドが最初に動いてほしいのか?全員一斉でいいのか?ランダムでいいのか?などにより、どのような方式を用いたらいいのかは微妙に異なってきます。

1.『Concurrent Programming in Java』
2.『CONCURRENCY STATE MODELS&JAVA PROGRAMMING』
3.『JAVA CONCURRENCY IN PRACTICE』
あたりを読んでください。

JAVAの常駐並行処理入門として、個人的には"2."がお勧めですが、"3."は日本語版も(『Java並行処理プログラミング ―その「基盤」と「最新API」を究める― 』)も出たようです。

参考URL:http://www.amazon.co.jp/95-Brain-Goetz/dp/4797337206/sr=8-1/qid=1169899718/ref=sr_1_1/503-5711274-7224761

投稿日時 - 2007-01-27 21:39:23

あなたにオススメの質問