荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Lg (从零开始), 信区: Java
标  题: “生产者―消费者”问题
发信站: 深圳大学荔园晨风电子公告牌 (Wed Apr 29 13:55:38 1998), 站内信件

    如何用JAVA来实现
               “生产者―消费者”问题

   夏军

   生产者和消费者问题是从操作系统中的许多实际同步问题中抽象出来的具有代
 表性的问题。它反映了操作系统中典型的同步例子。

   生产者进程(进程由多个线程组成)生产信息,例如它可以是计算进程。消费者
 进程使用信息,它可以是输出打印进程。由于生产者和消费者彼此独立,且运行速
 度不确定,所以很可能出现生产者已产生了信息而消费者却没有来得及接受信息这
 种情况。为此,需要引入由一个或者若干个存储单元组成的临时存储区,以便存放
 生产者所产生的信息,平滑进程间由于速度不确定所带来的问题。这个临时存储区
 叫做缓冲区,通常用一维数组来表示。

   由一个或若干个存储单元组成的缓冲区叫作“有穷缓冲区”。下面我们来分析
 一下有穷缓冲的生产者和消费者的例子。

   假设有多个生产者和多个消费者,它们共享一个具有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){}

    }

    }

   }

   上述程序在Windows 95的JDK 1.0.2下通过,它通过改变produce_speed
  、consume_speed 来改变生产者进程和消费者进程的速度。

--
☆ 来源:.深大荔园晨风 bbs.szu.edu.cn.[FROM: www-post@linux.szu.e]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店