生产者-消费者(producer-consumer)问题,两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。
这样应该是生产者生产一个产品,然后消费者取走一个产品,然后再生产、再消费,这个看似很理所当然的逻辑在现实中是必然的,但是在程序里却出现了问题。a:生产者生产了很多消费者却没有取,b:生产这还没有生产完一个完整的产品消费者却已经取走了好几次了,这样取走的产品当然是不合格的。
下面就用生产和消费鞋子为例,看看程序是怎么运行的吧.. .. ..
Demo01
package demo;
class Shoes{
// 鞋子类,两个属性:使用者(男/女),大小(大/小)
String user=null;
String size=null;
}
class Pro implements Runnable{
// 生产者,生产
Shoes shoe = null;
public Pro(Shoes s){
this.shoe=s;
}
public void run(){
int i=0;
while(true){
if(i==0){
// 男人穿的鞋子是大号的
shoe.user="男式";
shoe.size="大号";
i=1;
}else{
// 女人穿的鞋子是小号的
shoe.user="女式";
shoe.size="小号";
i=0;
}
}
}
}
class Cus implements Runnable{
Shoes shoe=null;
public Cus(Shoes s){
this.shoe=s;
}
public void run(){
while(true){
System.out.println(shoe.user+"-->"+shoe.size);
}
}
}
public class Demo01 {
/**生产者-消费者问题 producer-consumer
* @param args
*/
public static void main(String[] args) {
// 设置鞋子的一个生产者和一个消费者,并启动两个线程,分别进行生产和消费
Shoes shoe = new Shoes();
Pro p = new Pro(shoe);
Cus c = new Cus(shoe);
new Thread(p).start();
new Thread(c).start();
}
}
结果:
从结果中可以看到,第一次取时已经生产完一双男鞋,女鞋还没有生产完就取走了女鞋,第二次到第四次消费都是男鞋,看来是要么生产的太多了,没有取走,要么就是取的太快,只生产了一双男鞋却取了四次。
这样的程序显然是不符合实际的,所以就要加以改进。
应该是生产时,生产者进入车间并把车间的门上锁,生产一双后生产者出来,消费者进入到车间并把车间门上锁,取到鞋子后出来,这样车间里只有一个人,要么生产者要么消费者,这样就可以保证生产合格的产品。
改进的程序:
Demo02
package demo2;
class Shoes{
// 鞋子类,两个属性:使用者(男/女),大小(大/小)
String user=null;
String size=null;
private boolean flag = true;
public synchronized void set(String user,String size){
//如果flag的值不是true则要等待
if (!flag){
//等待
try{
wait();
}catch(Exception e){}
}
try{
Thread.sleep(100);
}catch (Exception e){}
// 如果向下继续执行了,则表示可以设置,flag = true
this.user = user;
this.size = size;
// 修改设置的标志
flag = false;
//唤醒其他线程
notify();
}
//设置一个输出方法
public synchronized void get(){
// 如果flag的值为true的时候,表示要等待
if(flag){
try{
wait();
}catch(Exception e){}
}
try{
Thread.sleep(100);
}catch (Exception e){}
//如果向下执行了,则表示允许取出
System.out.println(this.user+" --> "+this.size);
//改变标志,表示可以生产了
flag = true;
notify();
}
}
class Pro implements Runnable{
// 生产者,生产
Shoes shoe = null;
public Pro(Shoes s){
this.shoe=s;
}
public void run(){
int i=0;
while(true){
if(i==0){
// 男人穿的鞋子是大号的
shoe.set("男式", "大号");
i=1;
}else{
// 女人穿的鞋子是小号的
shoe.set("女式", "小号");
i=0;
}
}
}
}
class Cus implements Runnable{
Shoes shoe=null;
public Cus(Shoes s){
this.shoe = s;
}
public void run(){
while(true){
shoe.get();
}
}
}
public class Demo02 {
/**生产者-消费者问题 producer-consumer
* @param args
*/
public static void main(String[] args) {
// 设置鞋子的一个生产者和一个消费者,并启动两个线程,分别进行生产和消费
Shoes shoe = new Shoes();
Pro p = new Pro(shoe);
Cus c = new Cus(shoe);
new Thread(p).start();
new Thread(c).start();
}
}
运行结果:
posted on 2010-11-12 23:30
Mineralwasser 阅读(241)
评论(0) 编辑 收藏