Я пишу программу, реализующую проблему производителя-потребителя на Java с использованием концепции многопоточности. Ниже несколько деталей, как я должен это сделать:
1) Основной поток должен создать буфер с емкостью, указанной в качестве аргумента командной строки. Количество потоков производителя и потребителя также указывается в качестве аргументов командной строки. Я должен присвоить уникальный номер каждому потоку-производителю и потребителю. Как присвоить уникальный номер потокам производителя и потребителя?
2) Поток-производитель работает в бесконечном цикле. Он создает элемент данных (строку) в следующем формате: <producer number>_<data item number>
. Например, 1-й элемент данных из потока № 1 будет 1_1, а второй элемент данных из потока № 3 будет 3_2. Как создавать элементы данных в таком формате?
3) Затем поток производителя записывает запись в файл журнала производителя (‹ номер производителя > «Сгенерировано» <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);
}
}
}
Как я могу выполнить вышеуказанные шаги?