マルチスレッドの概念を使用して Java で Producer Consumer の問題を実装するプログラムを作成しています。以下は、私がそれを行うことになっている方法の詳細です。
1) メイン スレッドは、コマンド ライン引数として指定された容量でバッファを作成する必要があります。プロデューサ スレッドとコンシューマ スレッドの数も、コマンド ライン引数として指定されます。各生産者スレッドと消費者スレッドに一意の番号を割り当てることになっています。プロデューサー スレッドとコンシューマー スレッドに一意の番号を割り当てるにはどうすればよいですか?
2) 生産者スレッドは無限ループで動作します。次の形式のデータ項目 (文字列) を生成します<producer number>_<data item number>
。たとえば、スレッド番号 1 の最初のデータ項目は 1_1 になり、スレッド番号 3 の 2 番目のデータ項目は 3_2 になります。このような形式でデータ項目を作成するにはどうすればよいですか?
3) 次に、Producer スレッドがエントリを Producer ログ ファイルに書き込みます (< Producer number > "Generated" <data item>
)。ログ エントリを書き込むと、バッファに挿入しようとします。挿入が成功すると、ログ ファイルにエントリが作成されます ( <producer number> <data item>
「挿入成功」)。そのようなコードを書くにはどうすればよいですか?
以下は私が書いたJavaコードです。
import java.util.*;
import java.util.logging.*;
public class PC2
{
public static void main(String args[])
{
ArrayList<Integer> queue = new ArrayList<Integer>();
int size = Integer.parseInt(args[2]);
Thread[] prod = new Thread[Integer.parseInt(args[0])];
Thread[] cons = new Thread[Integer.parseInt(args[1])];
for(int i=0; i<prod.length; i++)
{
prod[i] = new Thread(new Producer(queue, size));
prod[i].start();
}
for(int i=0; i<cons.length; i++)
{
cons[i] = new Thread(new Consumer(queue, size));
cons[i].start();
}
}
}
class Producer extends Thread
{
private final ArrayList<Integer> queue;
private final int size;
public Producer(ArrayList<Integer> queue, int size)
{
this.queue = queue;
this.size = size;
}
public void run()
{
while(true){
for(int i=0; i<size; i++)
{
System.out.println("Produced: "+i+" by id " +Thread.currentThread().getId());
try
{
produce(i);
Thread.sleep(3000);
}
catch(Exception e)
{
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, e);
}
}}
}
public void produce(int i) throws InterruptedException
{
while(queue.size() == size)
{
synchronized(queue)
{
System.out.println("Queue is full "+Thread.currentThread().getName() +" is waiting, size: "+queue.size());
queue.wait();
}
}
synchronized(queue)
{
queue.add(i);
queue.notifyAll();
}
}
}
class Consumer extends Thread
{
private final ArrayList<Integer> queue;
private final int size;
public Consumer(ArrayList<Integer> queue, int size)
{
this.queue = queue;
this.size = size;
}
public void run()
{
while(true)
{
try
{ System.out.println("Consumed: "+consume());
Thread.sleep(1000);
}
catch(Exception e)
{
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, e);
}
}
}
public int consume() throws InterruptedException
{
while(queue.isEmpty())
{
synchronized(queue)
{
System.out.println("Queue is empty "+Thread.currentThread().getName()+" is waiting, size: "+queue.size());
queue.wait();
}
}
synchronized (queue)
{
queue.notifyAll();
System.out.println("Consumed by id "+Thread.currentThread().getId());
return (Integer) queue.remove(0);
}
}
}
上記の手順を実行するにはどうすればよいですか?