设计模式:生产者与消费者

生产者和消费者指的是两个不同的线程类对象,操作同一资源的情况

  • 生产者负责生产数据,消费者负责取走数据
  • 生产者每生产一组数据之后,消费者就要取走一组数据

会出现 数据错乱问题还有 数据重复取出,数据重复设置

要想解决数据错乱问题,采用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()进行唤醒

猜你喜欢

转载自blog.csdn.net/guo_binglo/article/details/80534908
今日推荐