洛神赋

子虚乌有

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  7 Posts :: 10 Stories :: 0 Comments :: 0 Trackbacks

线程间通信:一个线程向数据存储空间添加数据(唐老鸭),另一个线程从数据存储空间取出数据(米琪)。

程序有两种以外需要考虑:

1、      假设唐老鸭线程刚向数据存储空间添加了一辆车的名字。还没有加入这辆车的颜色,CPU就切换到了米琪线程,唐老鸭线程将把这辆车的名字和上辆车的颜色联系到了一起。

2 、唐老鸭了若干次的数据。米琪才开始取数据,或者是,米琪取完了一个数据后,还没等到唐老鸭放入新的数据,又重复取出已取过的数据。

可能出现的问题:

1唐老鸭米琪快时,米琪会漏掉一些数据没有取到。

2、      米琪唐老鸭快时,米琪取相同的数据。

多个线程共享同一资源的时候,必须进行同步,采用同步方法,解决第一个问题。

线程的等待和唤醒机制:

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

notify():唤醒同一对象监视器中调用wait的第一个线程。

程序中采用线程的等待和唤醒机制,当发现米琪没有取走内容时,唐老鸭应该等待,当米琪把内容取走之后,唐老鸭才可以放。这样解决了第二个问题。


代码如下:


package Killva.IOchaper4.o3;


class Animal{
 private String name ="唐老鸭";
 private String  sex= "公";
 private boolean flag=false;
 
 public synchronized void set(String name, String sex){//生产者
  //如果flag的值不是true则要等待
  
  if(!flag){
   //等待
   try{
    wait();
   }catch(Exception e){}
   
  }
  //如果向下继续执行了,则表示可以设置, flag =true
  this.name=name;
  this.sex=sex;
  //修改设置的标志
  flag = false;
  //唤醒其他线程
  notify();
 }
 //设置一个输出的方法
 public synchronized void get(){
  //如果flag的值为true的时候,表示要等待
  if(flag){
   try{
    wait();
    
   }catch(Exception e){}
   
  }
  //如果向下执行了,就表示允许
  System.out.println(this.name+"-->"+this.sex);
  //改变标签
  flag =true;
  notify();
 }
}

class Pro implements Runnable{
 Animal per =null;
 public Pro(Animal p){
  this.per=p;
  
 }
 public void run() {
  int i =0;
  
  while (true){
   
   if(i==0){
    per.set("米琪", "母");
    i=1;
    
   }else{
    per.set("唐老鸭", "公");
    i=0;
   }
  }
 }
}

class Cus implements Runnable{
 Animal per =null;
 public Cus(Animal p){
  this.per=p;
 }
 public void run() {
  while(true){
     per.get();
  }
 }
}


public class Demo01 {
 //主方法
 public static void main(String[] args){
  Animal per =new Animal();
  Pro p =new Pro(per);
  Cus c =new Cus(per);
  
  new Thread(p).start();
  new Thread(c).start();
  
 }

}

运行结果:




感谢阅读 !!!欢迎交流!!!    QQ:237333696
posted on 2010-11-13 11:12 洛神赋 阅读(910) 评论(0)  编辑  收藏

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


网站导航: