生產(chǎn)者和消費者問題是從操作系統(tǒng)中的許多實際同步問題中抽象出來的具有
代表性的問題。它反映了操作系統(tǒng)中典型的同步例子。
生產(chǎn)者進程(進程由多個線程組成)生產(chǎn)信息,例如它可以是計算進程。消費
者進程使用信息,它可以是輸出打印進程。由于生產(chǎn)者和消費者彼此獨立,且運
行速度不確定,所以很可能出現(xiàn)生產(chǎn)者已產(chǎn)生了信息而消費者卻沒有來得及接受
信息這種情況。為此,需要引入由一個或者若干個存儲單元組成的臨時存儲區(qū),
以便存放生產(chǎn)者所產(chǎn)生的信息,平滑進程間由于速度不確定所帶來的問題。這個
臨時存儲區(qū)叫做緩沖區(qū),通常用一維數(shù)組來表示。
由一個或若干個存儲單元組成的緩沖區(qū)叫作“有窮緩沖區(qū)”。下面我們來分
析一下有窮緩沖的生產(chǎn)者和消費者的例子。
假設有多個生產(chǎn)者和多個消費者,它們共享一個具有n個存儲單元的有窮緩沖
區(qū)Buffer(0……n-1),這是一個環(huán)形隊列。其隊尾指針Rear指向當前信息應存放
的位置(Buffer[Rear]),隊首指針Front指向當前取出信息的位置(Buffer[front
])。生產(chǎn)者進程總是把信息存放在Buffer[Rear]中,消費者進程則總是從Buffer
[Rear]中取出信息。如果想使生產(chǎn)者進程和消費者進程協(xié)調(diào)合作,則必須使它們
遵循如下規(guī)則:
1) 只要緩沖區(qū)有存儲單元,生產(chǎn)者都可往其中存放信息;當緩沖區(qū)已滿時,
若任意生產(chǎn)者提出寫要求,則都必須等待;
2) 只要緩沖區(qū)中有消息可取,消費者都可從緩沖區(qū)中取出消息;當緩沖區(qū)為
空時,若任意消費者想取出信息,則必須等待;
3) 生產(chǎn)者們和消費者們不能同時讀、寫緩沖區(qū)。
用JAVA 實現(xiàn)“生產(chǎn)者-消費者”問題的代碼如下:
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 實現(xiàn)的一中生產(chǎn)者和消費者的,代碼如下:
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 閱讀(247)
評論(0) 編輯 收藏 所屬分類:
java學習