1. 程式人生 > >執行緒間的經典案例

執行緒間的經典案例

該案例就是生產者與消費者之間的的問題

    1)假設生產者執行緒剛向資料儲存空間添加了資訊的名稱,還沒有加入資訊的內容,程式就切換到消費者執行緒,消費者執行緒將該資訊的名稱與上一個資訊的內容聯絡在一起。

    2)生產者放入了若干次的資料,消費者才開始去資料,或是消費者取完一個數據後,還沒等到生產者放入新的資料,又重複去已取出的資料

1.用同步解決資料錯位問題,即第一種情況

2.wait()//等待 ,notify()//喚醒第一個等待的程式,notifyAll()//喚醒全部等待的程式   

        來解決資料的重複取出和重複生產,即第二種情況


package run;


class Message {
private String title;
private String content;
private boolean flag = true;

// flag == true時,表示可以生產,但不能取走
// flag == false時,表示可以取走,但不能生產
public synchronized void set(String title, String content) {
if (this.flag == false) {// 表示已經生產過,不能生產
try {
super.wait();// 等待
} catch (InterruptedException e) {

e.printStackTrace();
}
}
this.title = title;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.content = content;
this.flag = false; // 已經生產完成,修改標誌位
super.notify(); // 喚醒執行緒
}


public synchronized void get() {
if (this.flag == true) { // 未生產,不能取走
try {
super.wait(); // 等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.title + "-->" + this.content);
this.flag = true; // 已經取走,繼續生產
super.notify(); // 喚醒等待執行緒
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getContent() {
return content;
}


public void setContent(String content) {
this.content = content;
}

public boolean isFlag() {
return flag;
}

public void setFlag(boolean flag) {
this.flag = flag;
}
}


package run;

class Producer implements Runnable {
   private Message msg =null;
    public Producer(Message msg){
//     this.msg = msg ;
    }
public void run() {
for(int x=0;x<50;x++){
if(x%2 ==0){
this.msg.set("李興華", "Java講師");
}else{
this.msg.set("mldn", "mldnjava");
}
}
}


}

package run;

public class Consumer implements Runnable {
  private Message msg =null;
    public Consumer(Message msg){
//     this.msg = msg;
    }
public void run() {
for(int x=0;x<20;x++){
this.msg.get();
}
}

}


package run;

public class TestDemo3 {

public static void main(String[] args) {
Message msg = new Message();
new Thread(new Producer(msg)).start();
new Thread(new Consumer(msg)).start();

}

}