线程间的经典案例

该案例就是生产者与消费者之间的的问题

    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();

}

}

猜你喜欢

转载自blog.csdn.net/qq_16773023/article/details/47703145