您的位置:首页 > 其它

多线程模拟生产者和消费者模型

2016-05-27 11:18 429 查看
模拟生产者一边生产数据,消费者一边取出数据,
但以下代码会出现数据错位现象和重复生产,不符合我们的要求

package com.wzy.java8.thread;

class Info{
private String title;
private String content;

public void setContent(String content) {
this.content = content;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public String getTitle() {
return title;
}

}
class Productor implements Runnable{
private Info info = null;
public Productor(Info info){
this.info = info;
}
@Override
public void run() {
for(int i=0;i<100;i++) {
if(i%2 == 0) {
this.info.setTitle("偶数");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.info.setContent("这是偶数");
}else{
this.info.setTitle("奇数");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.info.setContent("这是奇数");
}
}
}

}
class Consumers implements Runnable{
private Info info = null;
public Consumers(Info info) {
this.info = info;
}
@Override
public void run() {
for(int i=0;i<100;i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(info.getTitle()+"  "+info.getContent());
}
}

}
public class Demo2 {
public static void main(String[] args) {
Info info = new Info();
Productor p = new Productor(info);
Consumers c = new Consumers(info);
new Thread(p).start();
new Thread(c).start();

}
}


奇数  这是偶数
偶数  这是奇数
奇数  这是偶数
偶数  这是奇数
奇数  这是偶数


使用同步synchronized可以解决数据错位问题

使用super.wait(),super.notify();可以解决重复生产问题

思路:对于生产者:如果不可以生产,就休眠,等待正在取数据的消费者唤醒,被唤醒后,再生产,生产完成后唤醒消费者;消费者被唤醒后取数据,取完再唤醒生产者生产

对于消费者:如果不可以取数据,就休眠,等待正在生产的生产者唤醒,被唤醒后,取数据,取完后再唤醒生产者,生产者被唤醒后,继续生产

修改后代码如下:

package com.wzy.java8.thread;

class Info{
private String title;
private String content;
private boolean flag = true;
//true可以生产数据,不能取走数据
//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(100);
} 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();

}

}
class Productor implements Runnable{
private Info info = null;
public Productor(Info info){
this.info = info;
}
@Override
public void run() {
for(int i=0;i<100;i++) {
if(i%2 == 0) {
this.info.set("偶数", "这是偶数");
}else{
this.info.set("奇数", "这是奇数");
}
}
}

}
class Consumers implements Runnable{
private Info info = null;
public Consumers(Info info) {
this.info = info;
}
@Override
public void run() {
for(int i=0;i<100;i++) {

this.info.get();
}
}

}
public class Demo2 {
/*
* sleep() 是Thread的方法,休眠一定时间后会自动唤醒
* wait() 是Object的方法,必须等待其他线程notify(),notifyAll()来唤醒
* */

public static void main(String[] args) {
Info info = new Info();
Productor p = new Productor(info);
Consumers c = new Consumers(info);
new Thread(p).start();
new Thread(c).start();

}
}


奇数  这是奇数
偶数  这是偶数
奇数  这是奇数
偶数  这是偶数
奇数  这是奇数
偶数  这是偶数
奇数  这是奇数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: