這段時間一直跟我導師做一個本科班的java課助教,每天都向對那些無聊的問題,好煩!今天終於見到他們要做一個有難度一點的題目了:
Solve a single producer, single consumer problem using wait( ) and notify( ). The producer must not overflow the receiver's buffer, which can happen if the producer is faster than the consumer. If the consumer is faster than the producer, then it must not read the same data more than once. Do not assume anything about the relative speeds of the producer or consumer.
下面是相應的代碼,關鍵採用了多線程,這個例子不不僅允許一個生產者和一個消費者,任意多個都可以。
//產品類
class Produce
{
private String name;
public Produce(String name)
{
this.name=name;
}
public String toString()
{
return name;
}
}
/** 倉庫類*內部採用數組來表示迴圈隊列,以存放產品*/
class Storage
{
private static int CAPACITY=11;
private Produce[]
data=new Produce[CAPACITY];
private int front=0;
private int rear=0;
public Storage(final int capacity)
{
this.CAPACITY=capacity+1;
}
/***消費一個產品*/
public Produce
Consume()throws InterruptedException
{
synchronized(this)
{
while(front==rear)
{
this.wait();
}
int access=front;
front=(front+1+CAPACITY)%CAPACITY;
Produce produce =data[access];
System.out.println("Consumer["+ Thread.currentThread().getName()+"] consume:"+produce);
System.out.println("Storage condition: count="+(rear+CAPACITY-front) %CAPACITY);
this.notify();
return produce;
}
}
/***生產一個產品*/
public void Produce(Produce produce)throws InterruptedException
{
synchronized(this)
{
while((rear+1)%CAPACITY == front)
{
this.wait();
}
data[rear]=produce; rear=(rear+1) %CAPACITY;
System.out.println("Producer["+Thread.currentThread().getName()+"] produce:"+ produce);
System.out.println("Storage condition: count="+(rear+CAPACITY-front) %CAPACITY);
this.notify();
}
}
}
/**
*生產者類,採用線程,類比生產者的行為
*/
class Producer extends Thread
{
private Storage storage;
private static int produceName=0;
public Producer(Storage storage,String name)
{
super(name);
this.storage=storage;
}
public void run()
{
while(true)
{
try
{
Produce produce=new Produce((++produceName)+"");
storage.Produce(produce);
sleep(100);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
break;
}
}
}
}
/**
*消費者,採用線程,類比消費者行為
*/
class Consumer extends Thread
{
private Storage storage;
public Consumer(Storage storage,String name)
{
super(name);
this.storage=storage;
}
public void run()
{
Produce produce;
while(true)
{
try
{
produce=storage.Consume();
sleep(500);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
break;
}
}
}
}
public class ProducerConsumer
{
public static void main(String[] args)
{
Storage storage=new Storage(10);
Producer producer1=new Producer(storage,"producer_01");
Producer producer2=new Producer(storage,"producer_02");
Consumer consumer1=new Consumer(storage,"consumer_01");
Consumer consumer2=new Consumer(storage,"consumer_02");
Consumer consumer3=new Consumer(storage,"consumer_03");
Consumer consumer4=new Consumer(storage,"consumer_04");
Consumer consumer5=new Consumer(storage,"consumer_05");
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
consumer3.start();
consumer4.start();
consumer5.start();
}
}