一. 生产者和消费者问题
生产者和消费者问题,是多线程中很常见的一种问题, 生产者生产产品,消费者消费产品,但同时,如果产品过多时,生产者暂停生产,让消费者抓紧消费, 如果产品没有时,消费者不能消费,让生产者抓紧生产。
生产的产品是一个实体类,如 Info 类, 里面有 name 和 content 两种属性。 注意,生产产品时,这两个属性应该是配套的, 消费时,也应该是配套的。
二. 生产者和消费者问题第一版
二.一 消息实体类 Info
很正常的 name 和 content 两种属性构成的 pojo.
public class Info { private String name; private String content; public Info(){ } public Info(String name,String content){ this.name=name; this.content=content; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "Info{" + "name='" + name + '\'' + ", content='" + content + '\'' + '}'; } }
二.二 生产者 Productor
public class Productor implements Runnable { private Info info; //传进来对象 public Productor(Info info){ this.info=info; } private boolean isFirst=true; @Override public void run() { for(int i=0;i<50;i++){ if(isFirst){ //是第一个,那么就生产第一个消息 this.info.setName("两个蝴蝶飞"); //生产消息,需要时间 try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setContent("这是两个蝴蝶飞"); isFirst=false; }else{ this.info.setName("老蝴蝶"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setContent("这是老蝴蝶"); isFirst=true; } } } }
二.三 消费者 Consumer
public class Consumer implements Runnable { private Info info; public Consumer(Info info){ this.info=info; } @Override public void run() { for(int i=0;i<50;i++){ //消费也需要时间 try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(info.toString()); } } }
二.四 主程序测试 Demo
public class Demo { public static void main(String[] args) { //定义产品对象 Info info=new Info(); //生产 和消费用同一个对象 Productor productor=new Productor(info); //消费 Consumer consumer=new Consumer(info); Thread thread=new Thread(productor); Thread thread1=new Thread(consumer); //启动 thread.start(); thread1.start(); } }
二.五 测试运行,发现问题
发现,取出的产品竟然乱套了。 这是没有同步的原因。
在设置内容时,需要进行同步, 在取出来内容时,也需要同步。
同步,需要放置在 Info 对象中进行处理。