当前页面: 开发资料首页 → Java 专题 → 如何用JAVA来实现“生产者―消费者”问题
摘要: 如何用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 、c
onsume_speed 来改变生产者进程和消费者进程的速度。
到论坛去,我有问题要问问
相关知识
Java图形类库概述
Java应用程序中图像按钮的实现
在网页上发布统计曲线
Java的网络功能与编程
如何从JAR和ZIP包中析取Java源文件
如何解决Java方面的问题
如何让 JAVA 程序在 NT 的服务中运行
java 经验大放送 1
upload
jsp已经稳定运行起来
gunjsp的安装,配置
a connection pool
Apache+JServ+ojsp+SSL+PHP(IMAP+LDAP+MYSQL) Install Guide
JAVA中的多线程
Java线程的深入探讨
Java多线程之"事件分发线程"----Event Dispatch Thread
 
↑返回目录 
前一篇: Java在Client/Server网络中的应用  
 
后一篇: java 经验大放送 1