質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

Q&A

解決済

1回答

2958閲覧

waitで停止したスレッドをnotifyAllに再度起動が行えません

alice-R

総合スコア18

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

0グッド

1クリップ

投稿2018/03/11 07:45

java

1public class Main { 2 public static void main(String[] args) throws InterruptedException { 3 // TODO Auto-generated method stub 4 ThreadProcess th1 = new ThreadProcess(1); 5 th1.start(); 6 Thread.sleep(100); 7 ThreadProcess th2 = new ThreadProcess(2); 8 th2.start(); 9 } 10 11}

java

1public class ThreadProcess extends Thread{ 2 private int num=0; 3 public ThreadProcess(int num) { 4 this.num = num; 5 } 6 public synchronized void run() { 7 try { 8 System.out.println("run start num:"+this.num); 9 10 if(num == 1) { 11 //gate.getRrequest(); 12 System.out.println("wait"); 13 wait(); 14 System.out.println("wait解除"); 15 }else { 16 //gate.putRequest(); 17 System.out.println("notifyAll"); 18 notifyAll(); 19 System.out.println("notifyAll完了"); 20 } 21 22 } catch (InterruptedException e) { 23 // TODO Auto-generated catch block 24 e.printStackTrace(); 25 } 26 } 27}

###行いたいこと
①Mainクラスより、スレッド1(num=1)を起動
②スレッド1(num=1)をwaitを呼び出すことにより停止します
③時間を開けて、スレッド2(num=2)を起動
④スレッド2(num=2)にてnotifyAllを呼び出し、停止しているスレッド1(num=1)を復帰

ログとしては以下のようになってほしいです

run start num:1
wait
run start num:2
notifyAll
notifyAll完了
wait解除

###現状
run start num:1
wait
run start num:2
notifyAll
notifyAll完了

しかし、現状としては
wait解除
のログが表示されず、プログラムも終了されません。

どのようにすれば、notifyAllにて停止したスレッドを復帰させることが出来るのでしょうか。
どなたかご教示頂けないでしょうか。
どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

waitとnotifyはそれを呼び出す対象の特定のオブジェクトに対するwait/notifyをするものであって、対象が違えば同期をとったことにはなりません。質問者さんのコードは以下をしているようなものなんです。

java

1Object a = new Object(); 2Object b = new Object(); 3... 4void waitForA() { 5 synchronized (a) { 6 a.wait(); // (A) 7 } 8} 9void notifyToB() { 10 synchronized (b) { 11 b.notify(); // (B) 12 } 13}

もうお分かりと思いますが、(B)を実行しても(A)には通知されません。(A)に通知するためにはa.notify()としなければならないのです(もちろんaに対するsynchronized blockの中で)。そのことに注意してコードを書きなおせば期待通りの動きが達成できるのではないでしょうか?

投稿2018/03/11 08:37

編集2018/03/11 09:21
KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

alice-R

2018/03/11 11:49

ご回答ありがとうございます。 大変分かりやすく説明して頂いたおかげで、不明点が解消できました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問