執行緒間的經典案例
該案例就是生產者與消費者之間的的問題
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) {
}
}
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) {
}
}
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();
}
}