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

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

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

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

マルチスレッド

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

1035閲覧

スレッドの待ち合わせ

grape_ll

総合スコア83

Java

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

マルチスレッド

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/07/20 01:06

質問内容

スレッドが交互に動くようにしたいのですが,notifyAll()がうまく動かせていないようで実行しても何も起こらないのですがなぜうまく動いてくれないかを教えていただきたいです.

コード

Java

1class CountTenE implements Runnable{ 2 int id=1; 3 static int sw=0; 4 CountTenE(int n){ 5 id=n; 6 } 7 public static void main(String[] args){ 8 (new Thread(new CountTenE(0))).start(); 9 (new Thread(new CountTenE(1))).start(); 10 } 11 12 public void run(){ 13 for(int i=0;i<10;i++){ waitAndPrint(i);} 14 } 15 16 synchronized void waitAndPrint(int i){ 17 try{ 18 while(sw==id) wait(); 19 }catch(InterruptedException e){} 20 21 System.out.println("Thread("+id+"):i="+i); 22 sw=id; 23 notifyAll(); 24 } 25}

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

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

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

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

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

guest

回答1

0

ベストアンサー

main関数ではスレッド2つ実行してるだけで、他の関数は実行されてません


while(sw==id) wait(); で止まるのはいいですが、synchronized が付いてるので他のスレッドはこの関数に割り込まれません
swもidも変わりようがないため、無限ループとなります

投稿2020/07/20 01:12

編集2020/07/20 01:34
y_waiwai

総合スコア88042

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

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

grape_ll

2020/07/20 01:14

class CountTenE implements Runnable{ int id=1; static int sw=0; CountTenE(int n){ id=n; } public static void main(String[] args){ for(int i=0;i<2;i++){ Thread th=new Thread(new CountTenE(i)); th.start(); } } public void run(){ for(int i=0;i<10;i++){ waitAndPrint(i);} } synchronized void waitAndPrint(int i){ try{ while(sw==id) wait(); }catch(InterruptedException e){} System.out.println("Thread("+id+"):i="+i); sw=id; notifyAll(); } } のようにしたら Thread(1):i=0 は表示されたのですがこれだとなぜ途中で止まってしまうのでしょうか
y_waiwai

2020/07/20 01:34

回答に追記しました
grape_ll

2020/07/20 01:41

synchronizedで袋小路になっているのは理解できたのですが,これを外すとエラーが出てしまいました. swとidはどのようにすれば適した形に変化させることができますでしょうか.
xebme

2020/07/20 01:53

モニターを共有していないから。スレッドのインスタンスは2つありそれぞれが勝手に自分自身のモニターを獲得している。wait()しても自分でnotify()するしかない。できないので止まったまま。2つのスレッドが共有できるObjectを用意してモニターを獲得する/synchrozizedすること。
grape_ll

2020/07/20 01:59

二つのスレッドが共有するものはThread thで描いていたつもりなのですが,これだとダメということでしょうか.理解が浅くておかしな質問なのかもしれませんがよろしくお願いいたします.
grape_ll

2020/07/20 03:05

参考サイトの掲示,ありがとうございます. 時間がが切られていますので,すべてを読むことは出来ず,今回の該当箇所に当たりそうな箇所だけをかいつまんで読ませていただいきました. 二つのインスタンスがそれぞれ動いていて,waitを自分でnorifyしなければいけないということは理解できたのですが,その解決法が思いつきません.notifyAllは相手を指定できないのですよね. 共有のオブジェクトはどのようにして搭載すればよいのでしょうか.
xebme

2020/07/21 02:18

まず、java.lang.ObjectのAPIを読むこと。複数のスレッドから、あるオブジェクトへのアクセスを直列化したいのでwait/notifyを使うのです。 Object o = new Object(); // ロック用のオブジェクト sysncronized(o){} o.wait(); o.notifyAll();
grape_ll

2020/07/26 00:31

変数を追加して共通のものを作るのですね. 完全に発想の外でした.ご教授いただきありがとうございます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問