生产者和消费者问题是从操作系统中的许多实际同步问题中抽象出来的具有
代表性的问题。它反映了操作系统中典型的同步例子。
生产者进程(进程由多个线程组成)生产信息,例如它可以是计算进程。消费
者进程使用信息,它可以是输出打印进程。由于生产者和消费者彼此独立,且运
行速度不确定,所以很可能出现生产者已产生了信息而消费者却没有来得及接受
信息这种情况。为此,需要引入由一个或者若干个存储单元组成的临时存储区,
以便存放生产者所产生的信息,平滑进程间由于速度不确定所带来的问题。这个
临时存储区叫做缓冲区,通常用一维数组来表示。
由一个或若干个存储单元组成的缓冲区叫作“有穷缓冲区”。下面我们来分
析一下有穷缓冲的生产者和消费者的例子。
假设有多个生产者和多个消费者,它们共享一个具有n个存储单元的有穷缓冲
区Buffer(0……n-1),这是一个环形队列。其队尾指针Rear指向当前信息应存放
的位置(Buffer[Rear]),队首指针Front指向当前取出信息的位置(Buffer[front
])。生产者进程总是把信息存放在Buffer[Rear]中,消费者进程则总是从Buffer
[Rear]中取出信息。如果想使生产者进程和消费者进程协调合作,则必须使它们
遵循如下规则:
1) 只要缓冲区有存储单元,生产者都可往其中存放信息;当缓冲区已满时,
若任意生产者提出写要求,则都必须等待;
2) 只要缓冲区中有消息可取,消费者都可从缓冲区中取出消息;当缓冲区为
空时,若任意消费者想取出信息,则必须等待;
3) 生产者们和消费者们不能同时读、写缓冲区。
用JAVA 实现“生产者-消费者”问题的代码如下:
class MonitorTest{
static int produce_speed=200;
static int consume_speed=200;
public static void main (String [] args){
if(args.length>0)
produce_speed=Integer.parseInt(args[0]);
if(args.length>1)
consume_speed=Integer.parseInt(args[1]);
Monitor monitor=new Monitor();
new Producer(monitor,produce_speed);
new Consumer(monitor,consume_speed);
try{
Thread.sleep(4000);
}catch(InterruptedException e){}
System.exit(0);
}
}
class Monitor {
int Buffer_Length=10;
int[] Buffer=new int[Buffer_Length];
int Item;
int Count=0,Rear=0,Front=0;
//get buffer
synchronized int get(){
if(Count ==0)
try{
wait();
}catch(InterruptedException e){}
Item=Buffer[Front];
Count--;
Front=(Front+1)%Buffer_Length;
System.out.println("Got:"+Item);
notify();
return Item;
}
//set buffer
synchronized void set(int value){
if(Count==Buffer_Length)
try{
wait();
}catch(InterruptedException e){}
Buffer[Rear]=value;
Count++;
Rear=(Rear+1)%Buffer_Length;
System.out.println("Set:"+value);
notify();
}
}
class Producer implements Runnable{
Monitor monitor;
int speed;
Producer(Monitor monitor,int speed){
This.monitor=monitor;
This.speed=speed;
new Thread(this,"Producer").start();
}
public void run(){
int i=0;
while(true){
monitor.set(i++);
try{
Thread.sleep((int)(Math.random()*speed));
}catch(InterruptedException e){}
}
}
}
class Consumer implements Runnable{
Monitor monitor;
int speed;
Consumer(Monitor monitor,int speed){
This.monitor=monitor;
This.speed=speed;
new Thread(this,"Consumer").start();
}
public void run(){
while(true){
monitor.get();
try{
Thread.sleep((int) (Math.random()*speed));
}catch(InterruptedException e){}
}
}
}
--------------------------------------------------------------------------------------------------------------------------------
Java example 实现的一中生产者和消费者的,代码如下:
import java.util.Random;
public class Consumer implements Runnable {
private Drop drop;
public Consumer(Drop drop) {
this.drop = drop;
}
public void run() {
Random random = new Random();
for (String message = drop.take(); ! message.equals("DONE");
message = drop.take()) {
System.out.format("MESSAGE RECEIVED: %s%n", message);
try {
Thread.sleep(random.nextInt(5000));
} catch (InterruptedException e) {}
}
}
}
import java.util.Random;
public class Producer implements Runnable {
private Drop drop;
public Producer(Drop drop) {
this.drop = drop;
}
public void run() {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
Random random = new Random();
for (int i = 0; i < importantInfo.length; i++) {
drop.put(importantInfo[i]);
try {
Thread.sleep(random.nextInt(5000));
} catch (InterruptedException e) {}
}
drop.put("DONE");
}
}
public class Drop {
//Message sent from producer to consumer.
private String message;
//True if consumer should wait for producer to send message, false
//if producer should wait for consumer to retrieve message.
private boolean empty = true;
public synchronized String take() {
//Wait until message is available.
while (empty) {
try {
wait();
} catch (InterruptedException e) {}
}
//Toggle status.
empty = true;
//Notify producer that status has changed.
notifyAll();
return message;
}
public synchronized void put(String message) {
//Wait until message has been retrieved.
while (!empty) {
try {
wait();
} catch (InterruptedException e) {}
}
//Toggle status.
empty = false;
//Store message.
this.message = message;
//Notify consumer that status has changed.
notifyAll();
}
}
public class ProducerConsumerExample {
public static void main(String[] args) {
Drop drop = new Drop();
(new Thread(new Producer(drop))).start();
(new Thread(new Consumer(drop))).start();
}
}
posted on 2010-10-12 17:06
fly 阅读(244)
评论(0) 编辑 收藏 所属分类:
java学习