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

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

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

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

Q&A

1回答

2837閲覧

Java スレッド同士の待ち合わせについて

M.M.O-05

総合スコア15

Java

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

0グッド

0クリップ

投稿2016/12/16 05:52

###前提・実現したいこと
入門書を参考にしました。
スレッド同士を待ち合わせるプログラムで、
3つのproducerと3つのconsumerが5つのキューで数字を入れ食いするプログラム(見ていただければわかると思います。)を作りたいのですが、どうすれば現在それぞれ2つずつのproducerとconsumerを3つずつランダムに動かせますか?
できれば具体的に教えていただけると助かります。
ご回答よろしくお願いいたします。

###該当のソースコード

java

1package thread; 2 3public class ProducerConsumer { 4 5 public static void main(String[] args) { 6 MyQueue queue = new MyQueue(5); 7 Producer producer = new Producer(queue); 8 Consumer comsumer = new Consumer(queue); 9 producer.start(); 10 comsumer.start(); 11 } 12} 13 14class MyQueue{ 15 int[] intbuf; 16 int start; 17 int count; 18 public MyQueue(int size){ 19 intbuf = new int[size]; 20 start = 0; 21 count = 0; 22 } 23 public synchronized void put(int n) throws InterruptedException{ 24 while(count >= intbuf.length){ 25 System.out.println(Thread.currentThread().getName() +"wait: バッファの空きを待つ"); 26 wait(); 27 } 28 int end = (start + count) % intbuf.length; 29 intbuf[end] = n; 30 count++; 31 notifyAll(); 32 } 33 public synchronized int take() throws InterruptedException{ 34 while(count== 0){ 35 System.out.println(Thread.currentThread().getName() + "wait:データを待つ"); 36 wait(); 37 } 38 int n = intbuf[start]; 39 start = (start+1) % intbuf.length; 40 count--; 41 notifyAll(); 42 return n; 43 } 44} 45class Producer extends Thread{ 46 static final int END = -1; 47 MyQueue queue = null; 48 Producer(MyQueue queue){ 49 this.queue = queue; 50 } 51 public void run(){ 52 try{ 53 for (int i = 1;i<100;i++){ 54 int n = produce(i); 55 queue.put(n); 56 } 57 queue.put(Producer.END); 58 }catch(InterruptedException e){ 59 } 60 } 61 int produce(int n){ 62 sleepRandomly(); 63 System.out.println("Producer:"+Thread.currentThread().getName() +"は"+"を生産完了"); 64 return n; 65 } 66 void sleepRandomly(){ 67 try{ 68 int n = (int)(Math.random()*1000); 69 Thread.sleep(n); 70 }catch (InterruptedException e){ 71 } 72 } 73} 74 75class Consumer extends Thread{ 76 MyQueue queue = null; 77 Consumer(MyQueue queue){ 78 this.queue = queue; 79 } 80 81 public void run(){ 82 try{ 83 while(true){ 84 int n = queue.take(); 85 if(n==Producer.END){ 86 break; 87 } 88 consume(n); 89 } 90 }catch(InterruptedException e){ 91 } 92 } 93 void consume(int n){ 94 System.out.println("consumer:"+Thread.currentThread().getName()+"は"+n+"を消費中"); 95 sleepRandomly(); 96 } 97 void sleepRandomly(){ 98 try{ 99 int n = (int)(Math.random()*1000); 100 Thread.sleep(n); 101 }catch(InterruptedException e){ 102 } 103 } 104} 105

###実行結果

lang

1Thread-1wait:データを待つ 2Producer:Thread-0はを生産完了 3consumer:Thread-1は1を消費中 4Producer:Thread-0はを生産完了 5consumer:Thread-1は2を消費中 6Thread-1wait:データを待つ 7Producer:Thread-0はを生産完了 8consumer:Thread-1は3を消費中 9Producer:Thread-0はを生産完了 10consumer:Thread-1は4を消費中 11Thread-1wait:データを待つ 12Producer:Thread-0はを生産完了 13consumer:Thread-1は5を消費中 14Thread-1wait:データを待つ 15Producer:Thread-0はを生産完了 16consumer:Thread-1は6を消費中 17Thread-1wait:データを待つ 18Producer:Thread-0はを生産完了 19consumer:Thread-1は7を消費中 20Producer:Thread-0はを生産完了 21///

###試したこと
課題に対してアプローチしたことを記載してください

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

KSwordOfHaste

2016/12/16 06:00

課題に対してアプローチしたことを記載しましょう。あなたがどのくらい元のプログラムを理解しているかはっきりわかりません。
M.M.O-05

2016/12/16 07:44

キュークラスがいまいち理解できていません。
yohhoy

2016/12/16 07:56

「現在それぞれ2つずつのproducerとconsumer」とありますが、producer1個+consumer1個しかありませんよ?どのような動作をさせたいのか、改めて説明文を見直してください。
M.M.O-05

2016/12/16 08:00

すいません。producerとconsumerは一つずつでした。やりたいこととしてはproducerとconsumerをそれぞれ独立な3つにしたいということです。
yohhoy

2016/12/16 08:31 編集

もう少し丁寧に説明された方が良いです。producer3個+consumer3個を、単一キューを介してやりとりさせたいという事でしょうか?単純にProducerクラス/Consumerクラスを3インスタンスづつ(合計6インスタンス)作成すれば、スレッド自体は動きますよ? 追記:申し訳ありませんが、私では質問者さんの目的をくみとれません。他の回答者の方におまかせします。
M.M.O-05

2016/12/16 08:12

ありがとうございます。ProducerクラスとConsumerクラスは一つずつでお願いします。
jimbe

2019/01/23 02:38 編集

Producer:Thread-0はを生産完了 'は'と'を'の間にnが表示されていないようです. はともかく, yohhoyさんはクラスではなく「インスタンス」を必要なだけ作れば良いのではと言われています. 参考にされた入門書にクラスとインスタンスの関係・違いについて書かれている箇所がありましたら, その辺りを見直されることをお勧めします.
guest

回答1

0

ProducerとConsumerのインスタンスの合計数が奇数(3など)だったり両方の個数が不均衡な場合でも動くようにしたものが以下です

java

1import java.util.concurrent.BlockingQueue; 2import java.util.concurrent.LinkedBlockingQueue; 3import java.util.concurrent.TimeUnit; 4public class PRM{ 5 6 public static void main(String[] args) { 7 BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(5); 8 Producer producer = new Producer(queue); 9 10 Consumer comsumer = new Consumer(queue); 11 Consumer comsumer2 = new Consumer(queue); 12 13 producer.start(); 14 15 comsumer.start(); 16 comsumer2.start(); 17 18 } 19} 20 21class Producer extends Thread{ 22 static final int END = -1; 23 BlockingQueue<Integer> queue = null; 24 Producer(BlockingQueue<Integer> queue){ 25 this.queue = queue; 26 } 27 public void run(){ 28 try{ 29 for (int i = 1;i<10;i++){ 30 int n = produce(i); 31 queue.put(n); 32 } 33 34 }catch(InterruptedException e){ 35 } 36 } 37 int produce(int n){ 38 sleepRandomly(); 39 System.out.println("Producer:"+Thread.currentThread().getName() +"は"+n+"を生産完了"); 40 return n; 41 } 42 void sleepRandomly(){ 43 try{ 44 int n = (int)(Math.random()*1000); 45 Thread.sleep(n); 46 }catch (InterruptedException e){ 47 } 48 } 49} 50 51class Consumer extends Thread{ 52 BlockingQueue<Integer> queue = null; 53 Consumer(BlockingQueue<Integer> queue){ 54 this.queue = queue; 55 } 56 57 public void run(){ 58 try{ 59 while(true){ 60 int n = queue.poll(4,TimeUnit.SECONDS); 61 consume(n); 62 } 63 }catch(NullPointerException e){ 64 65 }catch(InterruptedException e){ 66 } 67 } 68 void consume(int n){ 69 System.out.println("consumer:"+Thread.currentThread().getName()+"は"+n+"を消費中"); 70 sleepRandomly(); 71 } 72 void sleepRandomly(){ 73 try{ 74 int n = (int)(Math.random()*1000); 75 Thread.sleep(n); 76 }catch(InterruptedException e){ 77 } 78 } 79}

投稿2016/12/16 09:56

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問