• ベストアンサー

スレッド

問題集を読んでいて、どうしても意味がわからなかった部分があります。五択になっていて、私は 「notify()実行の条件は、呼び出し元のスレッドが待機状態にあるスレッドのロックフラグを取得していることである」 を選んだんですが、これは間違いでした。 解説には待機スレッドのロックフラグは必要ではない、とあるのですが、では逆に言うとなんの(何処の)ロックフラグが必要になるのでしょうか? ご存知の方がいらっしゃいましたら、教えて下さい。 宜しくお願い致します。

  • Java
  • 回答数2
  • ありがとう数3

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

  • ベストアンサー
  • wo-007
  • ベストアンサー率68% (15/22)
回答No.2

notify()、notifyAll()、wait()を実行するには「排他処理対象のオブジェクトのロックを取得している」 必要があります。 そもそもロックとは何かいうと、 「オブジェクトを操作する上で、1つのスレッドにしか与えられない実行権利」です。 例をあげます。 オブジェクトAを排他処理の対象にしようとしています。スレッドBはオブジェクトAを操作しようとして、既に待ちの状態になっています。この場合、スレッドBの実行権利を取得しても何の意味もないですよね。オブジェクトAを操作する権利が必要ですよね。 ご理解いただけたでしょうか。

makinko0129
質問者

お礼

丁寧な説明をありがとうございます。 うーん、納得! スレッドについては(も?)まだまだなので、もっと勉強を頑張りたいと思います。 今回は本当にありがとうございました。

その他の回答 (1)

  • UKY
  • ベストアンサー率50% (604/1207)
回答No.1

できれば、他の選択肢の内容も教えていただけるとお答えしやすいのですが……

makinko0129
質問者

お礼

書き込みありがとうございました。 他の選択三つは、同期・排他制御に関する問題なのに、sleep()とかがでてきてるので、問題外なのです。 ちなみにその問題集の正解の答えは 「wait()実行の条件は、呼び出し元のスレッドが使用しているオブジェクトのロックフラグを取得していることである」でした。 今回は書き込みをしてくださり、ありがとうございました。

関連するQ&A

  • javaのwaitしてるスレッドをnotifyで起こすことが出来ない

    JDK1.5 WindowsXPです。 現在マルチスレッドを試しています。 A、B、C三つのスレッドがあります。 AはBというスレッドを作るメインスレッドです。 Bは、waitするスレッドです。 public final void run(){  while (true){   try {    //notifyが来るまで待機    waitForNotify();    //実際の処理    act();    //スレッド停止させるための割り込み例外   } catch (InterruptedException e) {    Thread.currentThread().interrupt();    e.printStackTrace();   }   //割り込み受信の場合強制終了する   if (Thread.currentThread().isInterrupted()) {    break;   }  } } こんな感じです。 そしてCのスレッドがnotify()を実行します。 しかしnotify()を実行してもスレッドは起きません。 Bに、 public synchronized void notifyM() throws InterruptedException{   wait(); } のようなメソッドを追加して、スレッドのインスタンスメソッドとして実行しても起きません。 notify()がJavaDOCなどを読んでも意味不明なため、 どのような使い方なら動くのか見当がつきませんので質問しました。 notify(スレッドB)みたいなら分かりいいんですが。

    • ベストアンサー
    • Java
  • デッドロック回避のためのwait() notify()

    学生です。最近javaの勉強をはじめました。 synchronized statementでデットロック回避のためにwait() notify()の使い方がよくわかりません。本にはwait()はスレッドがsynchronizedで獲得してあるロックを解放し、待機状態に入るとのことを書いてありましたが、なぜ、wait()をwhileループでまわすのでしょうか? それと、notifyは待機状態のスレッドに対して通知し、通知されたスレッドは待機状態から実行状態に移るとのことですが、whileループで再びwait()を実行し永遠に抜け出せないと思うのですがどうなんでしょうか? お手数ですが、詳しい方がいらしたら教えていただけないでしょうかお願いします。

  • スレッドの待機と再開

    お世話になります。 マルチスレッドのプログラムで悩んでいます。 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() を呼び出すものとします。 そして、それぞれのスレッドは、お互いのインスタンスを知りません。(説明しづらいので、補足要求があれば、ソースで示します。) よろしくお願いいたします。

    • ベストアンサー
    • Java
  • wait()したスレッドが起こされるタイミング

    以下のコードにおいて。 % java ThreadWaitTest 2 の場合はaと表示したまま止まりますが、 % java ThreadWaitTest 1 の場合はスレッドの終了に伴ってwait()が切れ、bまで表示します。 私の望む動作は前者です。 後者の場合、これはつまりスレッドをwaitした際の待機プールがスレッドオブジェクトの場合、そのスレッドの実行が終了すると待機プールにある待機スレッドを自動でnotify()してしまうことを意味していると思うのですが、この解釈はあっていますか? Java のAPIドキュメントに 「別のスレッドが notify メソッドまたは notifyAll メソッドを呼び出してこのオブジェクトのモニター上で待機するスレッドに通知を出すまで待機します」 とあるように、ユーザが明確的にnotifyしないと起こらないと思いこんでいました。 なぜこういう仕様になっているのでしょうか? また、この仕様について詳しく書いてあるサイトやドキュメントなどありませんでしょうか? public class ThreadWaitTest extends Thread {  public Object mutex = new Object();    public static void main(String[] args) {   try {    ThreadWaitTest test = new ThreadWaitTest();    test.start();    System.out.println("a");    switch (new Integer(args[0])) {    case 1:     synchronized(test) {      test.wait();     }     break;    case 2:     synchronized(test.mutex) {       test.mutex.wait();     }     break;    }    System.out.println("b");   } catch (InterruptedException ie) {    ie.printStackTrace();   }  }  public void run() {   try {    Thread.sleep(5000);   } catch (InterruptedException ie){    ie.printStackTrace();}   } }

    • ベストアンサー
    • Java
  • 交互にスレッド実行 (どうしてちゃんと動いてる?)

    http://oshiete1.goo.ne.jp/qa2968378.html で質問した者です。 2つのスレッドで1と2を交互に実行する以下のプログラム。 final Object obj1 = new Object(); //スレッド間通信用のobject final Object obj2 = new Object(); //スレッド間通信用のobject2 Thread t1 = new Thread() {  public void run() {   try {    while(true) {     System.out.print("1");     synchronized (obj1) {      synchronized (obj2) {       obj2.notify();//相手をnotifyして      }      obj1.wait();//自分はwait     }    }   } catech (Exception e){} }; Thread t2 = new Thread() {  public void run() {   try {    while(true) {     System.out.print("2");     synchronized (obj2) {      synchronized (obj1) {       obj1.notify();      }      obj2.wait();     }    }   } catch (Exception e){}  } }; Thread t1 = new Test1(); Thread t2 = new Test2(); t1.start(); while(t1.getState() != Thread.State.WAITING); t2.start(); が思ったように動いてはいるものの、なぜ正常に動いているかがわかりません。 t1が wait() したときはobj1のロックをもっていて、t2の synchronized (obj1){obj1.notify()} ブロックに入れず待機するはずだと思うのですが。 なぜちゃんと動いているのでしょう?

    • ベストアンサー
    • Java
  • wait中にinterruptを呼ばれたスレッドの振る舞いについて

    はじめまして。javaの初心者です。 どうしてもわからないことがあります。 例えば、以下のコードで、 class Foo { public synchronized void foo() { while(条件) { try { this.wait(); } catch(InterruptedException ex)    {     処理    } } } } wait中であったスレッドは、他のスレッドによって interrupt()メソッドを実行されたときは、Fooの ロックを取得してからcatch節を実行すると思うのですが、もし、以下のコードの場合は、 class Foo { public synchronized void foo() throws InterruptedException { while(条件) { this.wait(); } } } wait中であったスレッドは、他のスレッドによって interrupt()を実行されたときにすぐにInterrupted Exceptionをスローするのか、それとも Fooクラスのロックを取得してからInterruptedExceptionをスローするのかどちらなのか がわかりません。どうか教えてください。よろしく お願いします。

    • ベストアンサー
    • Java
  • スレッドの状態遷移について。。。

    Javaの本を買って読んでいます。 その中の「スレッド」のカテゴリーの「状態遷移」のところの「synchronized」の部分に、こう書かれています。 -------------------------- ・・・・・・ なお、sleepメソッドでスリープ状態(実行不可能状態)になったスレッドはロックを保持したまま開放しません。 そのため、ロックを取得できないで待たされるスレッドも実行不可能状態へ移行させられます。 -------------------------- これは、Synchronized指定されたメソッド(同期メソッド)の部分で出てきた文章でして、 私は、こう解釈しました。 → 例えば、同じオブジェクトの参照を引数とするスレッドが3つあり、その中の1つが『実行中』状態にある(仮に t1 とする)として(つまり残り2つ( t2 t3 )は『実行可能状態(プール)』にある。)、 実行中の t1 がsleep()メソッドで『実行不可能状態』になった場合、 『実行可能状態』にあった、t2 t3 も『実行不可能状態』へ移行する事になる。 間違っていますか? もし、この解釈が正しければ、こうなりますよね? t1・・・・・・・『実行中』 → 『実行不可能状態』 t2 t3・・・『実行可能状態』 → 『実行不可能状態』 ところが、状態遷移の5つの状態の図を見ると、 『実行可能状態』 から 『実行不可能状態』 へは、矢印→が書かれておりません。(逆向きの矢印がありますが。) どういう意味でしょうか。 java初心者ですが、 解りやすく教えて頂けると助かります。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • スレッド

    Thread th; //スレッド変数th宣言 public void start() {th = new Thread(); th.start();} //スレッドの開始 run(){Thread me = Thread.currentThread();      while(th == me){動作変数の処理} paint(){画像表示} 以上のような処理なのですが、 よく意味がわかりません。 特にwhile文の部分です。 currentThread とは?と聴いたところ 「現在実行中のスレッド」 だと言われました。 変数meに現在動作中のスレッドを代入する。 ??よく事情がわからないのです。 このプログラムはdrawOvalで丸を描いて、それを移動させると言うものなのですが、スレッドは2つ動いてると言うのです。動作変数処理と表示処理の2つだそうです。 で、meが動作、thが表示だと言うのですが正しいですか?まず通常動作するスレッドとth.start()で動くスレッドで、2つということはわかります。 で、現在実行中のスレッドと実行させたスレッドが等しい(trueまたはfalse)だと言うことが何を意味しているのか・・・????なのです・・・ これはどういうことなのでしょうか?? 質問してもまだ良くわからなそうなかおをしていたところ 「2つの処理を同時に処理するためと覚えてください」 と切り捨てられてしまいました。 これは正しいでしょうか・・・? 記述の足りない部分は補足いたします。 ご指摘お願いします。

    • ベストアンサー
    • Java
  • スレッドの停止方法の確認

    スレッドの停止方法の質問。 停止可能なスレッドを、私は以下のような形で書く事が多いのですが、インターネットで同様な コードを検索すると、2行目の停止フラグの宣言に volatile が無いものが無数に見つかります。 JSR-133 の簡単な解説を読んで、私なりに解釈した結果 volatile は必要と判断したのですが、これは間違いなのでしょうか? volatile は多少重たいので、できれば外したいのですが、 外してよい根拠が見つかりません。 真偽をご存知の方、よろしくお願い致します。 class MyThread extends Thread { private volatile boolean done = false; public void terminate(){ done = true; interrupt(); } public void run(){ while(!done){ //処理 } } }

    • ベストアンサー
    • Java
  • Tomcatのスレッドを破棄する方法

    はじめまして。 使用ツール:Tomcat 6.0 前提条件:Tomcatのserver.xmlでmaxThreads="1"と記述し、同時にスレッドが1つしか動作しないようにしている 質問: ブラウザでDBに登録されている全ての情報を取得し表示する時の動作。 ブラウザ(情報取得ボタン押下) ↓ サーブレット:DB(情報取得) ↓ ブラウザ(結果出力)  DBからの情報取得の処理が多少時間がかかってしまうため、その間にブラウザの中止ボタンが押下されてしまう場合があります。  その場合、ブラウザ⇔HTTPサーバ(Tomcat)でのセッションは切れているのですが、サーブレットの処理は継続して行われています。  再度、情報取得ボタンが押下されると、前提条件でスレッドが1つしか作成しないようにしているため、前の処理が終了するまで待機しするという形になっています。  この場合、中止→取得→中止→取得と何度も繰り返される(IEの場合取得ボタンを連打でも可)と、さらに結果の出力が遅くなるということがおきてしまいます。  これを解決するために、Tomcatが新しいリクエストを受け取った場合、現在のスレッドを破棄するといった形にできればと考えています。  上記の考えで調査を行っているのですが、良い情報を見つけることが出来ません。    実際にTomcatが現在実行中のスレッドを破棄し、新しいリクエストを受付けて処理を実行するといったようなことはできるのでしょうか?  ご存知の方がいらっしゃったら、どうか助言をよろしくお願いいたします。

専門家に質問してみよう