
以下のコードにおいて。
% 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();}
}
}
No.2ベストアンサー
- 回答日時:
自信なし。
---
"spruious wakeup"みたいですが・・・。
("spurious wakeup"については、
「1.5以降のjavadocのObject#wait(long)の項」、
または
「Effective Java 項50」
などに簡単に記されている)
(今のところ)仕様とはされてないが、
現実には認知されている現象、というところだと思います。
---
"spurious wakeup"については、よく知らないので、
ネットで検索したり、
sunの「Bug Database」などで検索してみてください。
http://bugs.sun.com/bugdatabase/view_bug.do?bug_ …
ご回答ありがとうございます。
wait()しか使っていなかったので、wait(long)の方に目を通していませんでした。
私が遭遇した「スレッドの終了時、そのスレッドオブジェクトの待機プールにある待機スレッドがnotify()される」という現象は spruious wakeup の一例に過ぎないのですかね。
ドキュメントに 稀に生じる と書いてあるところも怖いところです。
No.1
- 回答日時:
JDKにはそれらしい記述がありませんでしたね。
推測ですが、Threadが一度start()し、その後停止状態に遷移した場合、そのスレッドは二度とstart()できません。
もしnotify()を呼ぶ役目がそのThreadに課せられていたとしたら、二度とwait()状態から戻れない可能性もあるわけです。
ですので、「無効なオブジェクト」と化したThreadクラスは、その直前にnotifyAll()でもしているんじゃないでしょうか?
ご回答ありがとうございます。
>「無効なオブジェクト」と化したThreadクラスは、その直前にnotifyAll()でもしているんじゃないでしょうか?
うむむ、なるほど。
しかしこの現象をみつけるまで、プログラムのバグを特定できずえらい時間がかかってしまいました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java final 1 2022/06/10 22:49
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- JavaScript [Java] Edgeでのアドレスバー非表示について 3 2022/04/20 17:51
- Excel(エクセル) 【エクセルマクロ】既に開いているIEの、サイズや表示位置を変更するには 4 2022/12/01 22:57
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
jdbcでinsert,delete,createをe...
-
プログラミングの問題です。大...
-
Googleログインボタンのデザイ...
-
JDONWROADER2のエラー修復
-
「main メソッドを持つクラスが...
-
Eclipse 動的プロジェクトで404...
-
正規表現について質問です。 カ...
-
スプレッドシートからリマイン...
-
googleスプレッドシートのスク...
-
googleスプレッドシートのGASに...
-
Verilogについて質問です。この...
-
論理回路設計をVerilogで行う問...
-
ゲーム開発の入門書を探しています
-
session,requestはjspで未定義...
-
サーブレットをapacheで公開す...
-
下記のリストならno002が含まれ...
-
is this even a thing?
-
JAの支部?地域の農協のカード...
-
えハミルトン路と全域木のちが...
-
CSV出力を画面から選択したデー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
JDONWROADER2のエラー修復
-
Googleログインボタンのデザイ...
-
配列にnullを代入すると、null...
-
jdbcでinsert,delete,createをe...
-
「main メソッドを持つクラスが...
-
プログラミングの問題です。大...
-
eclipseで作ったプログラムを他...
-
正規表現について質問です。 カ...
-
Eclipse 動的プロジェクトで404...
-
マイクラでPythonのプログラミ...
-
jdk17.06のインストーラーが起...
-
自作Androidアプリのデータ引き...
-
直し方について教えて頂きたい...
-
eclipse実行ができない
-
サーブレットをapacheで公開す...
-
あんまりお料理しないのに台所...
-
CSV出力を画面から選択したデー...
-
次のhtml・cssでspan内の文字を...
-
問題作成のWebアプリの作り方を...
-
ゲーム開発の入門書を探しています
おすすめ情報