posts - 14,  comments - 7,  trackbacks - 0
       今天我们用实例程序说一下java中常见的生产者与消费者的问题。

 首先看一下里面线程间的通信问题:


   一个线程向数据存储空间添加数据(生产者),另一个线程从数据存储空间去出数据(消费者)。

这个程序中有两个可能出现的问题需要考虑:

1、         假设生产者线程刚向数据存储空间添加了一个食品的名字,还没有加入这个食品的属性,CPU就切换到了消费者线程,消费者线程将把这个食品的名字和这个人的属性联系在一起。

2、         消费者拿东西都希望自己拿到的是最新的,即生产者刚生产出,消费者就拿走,而不是拿一些陈旧的。可能出现消费者拿不了最新的在程序中的原因,生产者放了若干次的数据,消费者才开始取数据,或者是,消费者取完一个数据后,还没等到生产者放入新的数据,即消费者比生产者快时,又重复取出这个数据

    下面我们看一下具体的代码,来体验一下生产者与消费者的关系,平我们去吃麦当劳时,总会要点吃的喝的,比如我们吃个汉堡喝个咖啡,而且这些都要是最新的,都是他们现做的。

package com.dr.blog;

class M{
    String name 
= "Hamberger";
    String proper
="吃的";
    
boolean flag = false;
}

class Pro implements Runnable{
    M m 
= null;
    
public Pro(M m){
        
this.m=m;
    }

    
public void run(){
        
int i = 0;
        
while(true){
            
if(i==0){
                m.name
="Hamberger";
                m.proper
="吃的";
                i
=1;
            }
else{
                m.name
="cofe";
                m.proper
="喝的";
                i
=0;
            }

        }

    }

}

class Cus implements Runnable{
    M m 
= null;
    
public Cus(M m){
        
this.m= m;
    }

    
public void run(){
        
while(true){
            
try {
                Thread.sleep(
100);
            }
 catch (InterruptedException e) {
                
// TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println(m.name
+"----->"+m.proper);
            
        }

    }

}

public class ThreadDemo02{
    
public static void main(String[] args){
        M m 
= new M();
        Pro p 
= new Pro(m);
        Cus c 
= new Cus(m);
        
new Thread(p).start();
        
new Thread(c).start();
    }

}

运行结果如下:

可以看出这里出现了汉堡是喝的,咖啡是吃的的情况,也就是上面我们说的第一种情况,这个可以通过synchronized实现同步来解决,因为资源共享需要同步。
package com.dr.blog;

class M1 {
    String name 
= "Hamberger";
    String proper 
= "吃的";
    
//boolean flag = false;

    
public synchronized void set(String name,String proper){
        
//if(!flag){
            this.name= name;
            
this.proper=proper;
            
//flag = false;
        
//}
    }

     
public synchronized void get(){
        
//if(flag){
            System.out.println(this.name+"----->"+this.proper);
            
//flag = true;
            
//        }
                }

    
}


class Pro1 implements Runnable {
    M1 m 
= null;

    
public Pro1(M1 m) {
        
this.m = m;
    }


    
public void run() {
        
int i = 0;
        
while (true{
            
if (i == 0{
//                m.name = "Hamberger";
//                m.proper = "吃的";
                m.set("Hamberger""吃的");
                i 
= 1;
            }
 else {
//                m.name = "cofe";
//                m.proper = "喝的";
                m.set("cofe""喝的");
                i 
= 0;
            }

        }

    }

}


class Cus1 implements Runnable {
    M1 m 
= null;

    
public Cus1(M1 m) {
        
this.m = m;
    }


    
public void run() {
        
while (true{
            
try {
                Thread.sleep(
100);
            }
 catch (InterruptedException e) {
                
// TODO Auto-generated catch block
                e.printStackTrace();
            }

            m.get();
            
//System.out.println(m.name + "----->" + m.proper);
        }

    }

}


public class ThreadDemo01 {

    
public static void main(String[] args) {
        M1 m 
= new M1();
        Pro1 p 
= new Pro1(m);
        Cus1 c 
= new Cus1(m);
        
new Thread(p).start();
        
new Thread(c).start();
    }


}



 

第一个问题已经解决啦,但第二个问题还是存在,这个问题我们可以用线程的等待唤醒机制即wait(),notify()方法来解决

Wait()告诉当前线程放弃监视器并进入睡眠状态,直到其他线程进入同一监视器并调用notify()为止

Notify()唤醒同一对象监视器中调用wait()的第一线程


package com.dr.blog;

//package com.dr.blog;

class M2 {
    String name 
= "Hamberger";
    String proper 
= "吃的";
    
boolean flag = false;

    
public synchronized void set(String name,String proper){
        
if(!flag){
            
try{
                wait();
            }
catch(InterruptedException e){
                e.printStackTrace();
            }

            
this.name= name;
            
this.proper=proper;
            flag 
= false;
            notify();
        }

    }

     
public synchronized void get(){
        
if(flag){
            
try {
                wait();
            }
 catch (InterruptedException e) {
                
// TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println(
this.name+"----->"+this.proper);
            flag 
= true;
            notify();
                    }

                }

    
}


class Pro2 implements Runnable {
    M2 m 
= null;

    
public Pro2(M2 m) {
        
this.m = m;
    }


    
public void run() {
        
int i = 0;
        
while (true{
            
if (i == 0{
//                m.name = "Hamberger";
//                m.proper = "吃的";
                m.set("Hamberger""吃的");
                i 
= 1;
            }
 else {
//                m.name = "cofe";
//                m.proper = "喝的";
                m.set("cofe""喝的");
                i 
= 0;
            }

        }

    }

}


class Cus2 implements Runnable {
    M2 m 
= null;

    
public Cus2(M2 m) {
        
this.m = m;
    }


    
public void run() {
        
while (true{
            
try {
                Thread.sleep(
100);
            }
 catch (InterruptedException e) {
                
// TODO Auto-generated catch block
                e.printStackTrace();
            }

            m.get();
            
//System.out.println(m.name + "----->" + m.proper);
        }

    }

}


public class ThreadDemo03 {

    
public static void main(String[] args) {
        M2 m 
= new M2();
        Pro2 p 
= new Pro2(m);
        Cus2 c 
= new Cus2(m);
        
new Thread(p).start();
        
new Thread(c).start();
    }


}



现在我们开始说的两个问题已经解决啦!!
posted on 2010-11-10 23:07 迷人笑笑 阅读(2142) 评论(1)  编辑  收藏

FeedBack:
# re: java中消费者与生产者的问题实例解析
2010-12-14 17:17 | aben
楼主有没有搞错啊 你的最后那个截图后面不还是乱的吗 不是一个一个交替输出的啊  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2010年12月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(13)

随笔档案

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜