生产者-消费者同步问题
班级: 信安 091 姓名: 苏海 学号: 0907300426 日期:2011/11/15
1.实验目的
(1)全面理解生产者与消费者问题模型,掌握解决该问题的算法思想,正确使用同步
机制。
(2)学习使用多线程同步机制解决互斥和同步问题。
(3)使用 synchonized 关键字,wait()和 notify()函数解决多线程中资源同步的问题。
2.实验环境
已安装 win7 操作系统的微机一台、eclipse。
3.实验内容
请实现下面的生产者消费者问题:
有两个生产者,每个生产者每次可以生产 1 个产品,有一个消费者每次消费 2 个产品,
仓库最多只能存放 2 个产品,若仓库满,则生产者需等待空位来存放产品,若仓库产品数量
不足,则消费者需等待来消费产品。请用多线程技术实现以上功能,要求生产者存放产品时
按先来先服务的队列原则来存放产品。
功能要求:根据进程同步机制,编写一个解决上述问题的程序,可显示缓冲池状态、放
数据、取数据等过程。
4.具体设计要求及有关说明
(1)有 2 个生产者线程,分别为生产者 1 wQ1、生产者 2 wQ2;有 1 个消费者进程消
费者 rQ1;缓冲区 Queue,最大容量 maxMessageNum=2;
(2)共创建了主类 Run、生产者类 Producer、消费者类 Consumer、擦、产品类 Message
和存储区类 Queue。
(3)使用线程同步:synchonized 关键字,wait()和 notify()函数完成上述问题。
(4)程序运行流程图如下:(如不在外部中断,程序将一直循环运行)
开始
生产者
消费者
生产者生产
否
仓库是否满?
消费者等待
是
消费者消费
生产者等待
唤醒生产者
唤醒消费者
5.源代码
package Table;
//主线程
public class Run {
public static void main(String args[]) {
Queue Q = new Queue();
Producer wQ1 = new Producer("生产者1",Q);
Producer wQ2 = new Producer("生产者2",Q);
Consumer rQ1 = new Consumer("消费者",Q);
Thread threadWQ1 = new Thread(wQ1, "生产者1");
Thread threadWQ2 = new Thread(wQ2, "生产者2");
Thread threadRQ1 = new Thread(rQ1, "消费者");
threadWQ1.start();
threadWQ2.start();
threadRQ1.start();
}
}
//生产者类
class Producer extends Thread {
public String producerName;
private Queue queue;
Producer(String producerName,Queue queue) {
this.producerName = producerName;
this.queue = queue;
}
public void setProducerName(String producerName) {
this.producerName = producerName;
}
}
public String getProducerName() {
return producerName;
public void run() {
while (true) {
Message message = new Message();
message.setId(++Message.id);
message.setContent("产品"+Message.id);
queue.produce(message,producerName);
try {
sleep(1000);
} catch (Exception e) {
}
}
}
}
//消费者类
class Consumer extends Thread {
private String consumerName;
private Queue queue;
Consumer(String consumerName,Queue queue) {
this.consumerName = consumerName;
this.queue = queue;
}
public void setConsumerName(String consumerName) {
this.consumerName = consumerName;
}
}
public String getConsumerName() {
return consumerName;
public void run() {
while (true) {
queue.consume();
try {
sleep(2000);
} catch (Exception e) {
}
}
}
}
package Table;
//产品类
public class Message {
public static int id;
public String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getId() {
return id;
}
public void setId(int id) {
Message.id = id;
}
}
//存储区类
package Table;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Queue {
public List queue = new ArrayList();//存储产品
public LinkedList ProducerList= new LinkedList();//存
储排队等待的生产者
/** 队列中message对象的最大值,默认为2 */
int maxMessageNum = 2;
boolean flag=true;
public synchronized void produce(Message message,String producerName)
{
while (queue.size() == maxMessageNum) {
ProducerList.add(producerName);
if(flag==true){
flag=false;
this.notifyAll();
System.out.println(Thread.currentThread().getName()+" "+
"仓库已满, 进入生产等待队列第一位···"+" "+"目前库存量为
"+getCount());
try {
this.wait();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+" "+
"仓库已满, 进入生产等待队列第二位···"+" "+"目前库存量为"+getCount());
e.printStackTrace();
}
}
else{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//如果没有生产者等待
if(ProducerList.size()==0){
queue.add(message);
this.notifyAll();
System.out.println(Thread.currentThread().getName()+" "+ "生产
message.getContent() + " " +"目前库存量为"+ getCount());
了一个产品:"+" "+
}
//如果当前生产者是等待队列中第一位
else if(producerName==ProducerList.peekFirst()){
String Listproducer=ProducerList.pollFirst();
//如果除了第一位,还有生产者等待
if(ProducerList.size()!=0){System.out.println(Listproducer +" "+
"生产了一个产品:" + " " +
message.getContent() + " " +"目前库存量为"+ getCount()+"
"+ProducerList.getFirst()+"还在等待队列中等待 ");
//如果除了第一位,已经没有生产者等待
else{System.out.println(Listproducer +" "+ "生产了一个产品:" + " "
message.getContent() + " " +"目前库存量为"+ getCount());
}
+
}
} else
try {
wait();
}
this.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
public synchronized void consume() {
while (queue.size() == 0) {
System.out.println(Thread.currentThread().getName()+"
"+
"仓库已空, 正等待生产者生产···"+" "+"目前库存量为"+getCount());
this.notifyAll();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while (queue.size() == 1) {
System.out.println(Thread.currentThread().getName()+"
"目前库存量为 "+ getCount()+", 消费者正等待消费···");
this.notifyAll();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果仓库满,则进行一次消费,每次消费2个产品
while (queue.size() == 2) {
queue.removeAll(queue);
flag=true;
this.notifyAll();
System.out.println(Thread.currentThread().getName() +"
消费者进行一次消费···仓库已空"
+" "+"目前库存量为 "+ getCount());
try {
wait();
} catch (InterruptedException e) {
"+
"+ "
e.printStackTrace();
}
}
}
public synchronized int getCount() {
return queue.size();
}
}
6.实验结果