線程間通信:一個線程向數(shù)據(jù)存儲空間添加數(shù)據(jù)(Benz),另一個線程從數(shù)據(jù)存儲空間取出數(shù)據(jù)(BMW)。

程序有兩種以外需要考慮:

1、      假設(shè)Benz線程剛向數(shù)據(jù)存儲空間添加了一輛車的名字。還沒有加入這輛車的顏色,CPU就切換到了BMW線程,Benz線程將把這輛車的名字和上輛車的顏色聯(lián)系到了一起。

2、      Benz放了若干次的數(shù)據(jù)。BMW才開始取數(shù)據(jù),或者是,BMW取完了一個數(shù)據(jù)后,還沒等到Benz放入新的數(shù)據(jù),又重復(fù)取出已取過的數(shù)據(jù)。

可能出現(xiàn)的問題:

1、      BenzBMW快時,BMW會漏掉一些數(shù)據(jù)沒有取到。

2、      BMWBenz快時,BMW取相同的數(shù)據(jù)。

多個線程共享同一資源的時候,必須進(jìn)行同步,采用同步方法,解決第一個問題。

線程的等待和喚醒機(jī)制:

wait():告訴當(dāng)前線程放棄監(jiān)視器并進(jìn)入睡眠狀態(tài),直到其他線程進(jìn)入同一監(jiān)視器并調(diào)用notify為止。

notify():喚醒同一對象監(jiān)視器中調(diào)用wait的第一個線程。

程序中采用線程的等待和喚醒機(jī)制,當(dāng)發(fā)現(xiàn)BMW沒有取走內(nèi)容時,Benz應(yīng)該等待,當(dāng)BMW把內(nèi)容取走之后,Benz才可以放。這樣解決了第二個問題。

 

代碼如下:

package com.dr.test;

 

class Car{

       private String name="奔馳";

       private String color="銀色";

       private boolean flag=false;

       public synchronized void set(String name,String color){

              //如果flag的值不是true則要等待

              if(!flag){

                     //等待

                     try{

                            wait();

                     }catch(Exception e){}

              }

              //如果向下繼續(xù)執(zhí)行了,則表示可以設(shè)置,flag=true

              this.name=name;

              this.color=color;

              flag=false;

              notify();

       }

       public synchronized void get(){

              //如果flag的值為true的時候,表示要等待

              if(flag){

                     try{

                            wait();

                     }catch(Exception e){}

              }

              //如果向下執(zhí)行了,則表示允許取出

              System.out.println(this.name+"-->"+this.color);

              //改變標(biāo)志,表示可以生產(chǎn)了

              flag=true;

              notify();

       }

}

class Benz implements Runnable{

       Car car=null;

       public Benz(Car c){

              this.car=c;

       }

       public void run(){

              int i=0;

              while(true){

                     if(i==0){

                            car.set("寶馬", "紅色");

                            i=1;

                     }

                     else{

                            car.set("奔馳", "銀色");

                            i=0;

                     }

              }

       }

}

class BMW implements Runnable{

       Car car=null;

       public BMW(Car c){

              this.car=c;

       }

       public void run(){

              while(true){

                     car.get();

              }

       }

}

public class Demo01 {

 

      

       public static void main(String[] args) {

              Car c=new Car();

              Benz benz=new Benz(c);

              BMW bmw=new BMW(c);

              new Thread(benz).start();

              new Thread(bmw).start();

       }

 

}

 

運行結(jié)果: