该案例就是生产者与消费者之间的的问题
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();
}
}