生产者和消费者指的是两个不同的线程类对象,操作同一资源的情况
- 生产者负责生产数据,消费者负责取走数据
- 生产者每生产一组数据之后,消费者就要取走一组数据
会出现 数据错乱问题还有 数据重复取出,数据重复设置
要想解决数据错乱问题,采用synchronized同步方法才行
要想解决重复的问题,必须加入等待与唤醒机制,在Object类里面提供了专门的方法
- 等待:public final void wait()throws InterruptedException
- 唤醒第一个等待线程:public final void notify();
- 唤醒全部等待线程,哪个优先级高就先执行: public final void notifyAll();
package cn.xst.textdemoa;
class Product{
private String title;
private String content;
private boolean flag=true;
//flag=true:表示可以生产,但是不可以取走
//flag=false:表示可以取走,但是不可以生产
public synchronized void set(String title,String content){ //这是同步方法
if(flag==false){ //只能取走,不能生产 只有等变成true才可以
try {
super.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.title=title;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.content=content;
this.flag=false;//修改生产标记
super.notify();//唤醒其他等待线程
}
public synchronized void get(){ //同步方法 是为了防止数据错乱
if(this.flag==true){ //还没生产呢
try {
super.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(this.title+"--"+this.content);
this.flag=true;
super.notify();
}
}
class Productor implements Runnable{
private Product product;
public Productor (Product product){
this.product=product;
}
@Override
public void run() {
for(int x=0;x<100;x++){
if(x %2 ==0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.product.set("萧**","丑男");
}else{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.product.set("陈**","美女");
}
}
}
}
class Consumer implements Runnable{
private Product product;
public Consumer(Product product){
this.product=product;
}
@Override
public void run() {
for(int x=0;x<100;x++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.product.get();
}
}
}
public class ShengChanXiaoFei {
public static void main(String[] args) {
Product product=new Product();
new Thread(new Productor(product)).start(); //负责生产
new Thread(new Consumer(product)).start(); //复制取走
}
}
sleep()与wait()的区别
- sleep()是Thread类定义的方法,wait()是Object类定义的方法
- sleep()可以设置休眠时间,时间一到自动唤醒,而wait()需要等待notify()进行唤醒