需求:生产者生产一个,消费者消费一个
问题引出
class Info{ private String name; private String desc; public Info(){ } public Info(String name,String desc){ this.name = name; this.desc = desc; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } @Override public String toString() { return "Info{" + "name='" + name + '\'' + ", desc='" + desc + '\'' + '}'; }}class Product implements Runnable{ private Info info; public Product(Info info){ this.info = info; } @Override public void run() { for(int i = 0;i<100;i++){ if(i % 2 == 0){ this.info.setName("小郑"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setDesc("钢笔"); }else{ this.info.setName("小李"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setDesc("笔记本"); } System.err.println(info.getName()+" 生产->"+info.getDesc()); } }}class Consume implements Runnable{ private Info info; public Consume(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.err.println(info.getName()+"消费->"+info.getDesc()); } }}public class ProductCustumer { public static void main(String args[]){ Info info = new Info(); new Thread(new Product(info)).start(); new Thread(new Consume(info)).start(); }}
结果:小郑消费->null小郑 生产->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李 生产->笔记本小李消费->笔记本小郑 生产->钢笔小李消费->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李 生产->笔记本小李消费->笔记本小郑 生产->钢笔小郑消费->钢笔小李消费->笔记本小李 生产->笔记本小郑 生产->钢笔小李消费->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李 生产->笔记本小李消费->笔记本小郑消费->钢笔小郑 生产->钢笔小李 生产->笔记本小李消费->笔记本小郑 生产->钢笔小郑消费->钢笔小李 生产->笔记本小李消费->笔记本小郑 生产->钢笔小李消费->钢笔小李消费->笔记本小李 生产->笔记本小郑 生产->钢笔小郑消费->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->钢笔小郑 生产->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->钢笔小郑 生产->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->钢笔小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->钢笔小郑 生产->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李 生产->笔记本小李消费->笔记本小郑 生产->钢笔小郑消费->钢笔小李消费->笔记本小李 生产->笔记本小郑 生产->钢笔小郑消费->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑 生产->钢笔小郑消费->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李 生产->笔记本小李消费->笔记本小郑消费->钢笔小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑 生产->钢笔小李消费->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李 生产->笔记本小李消费->笔记本小郑 生产->钢笔小郑消费->钢笔小李 生产->笔记本小李消费->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑 生产->钢笔小郑消费->钢笔小李消费->钢笔小李 生产->笔记本小郑 生产->钢笔小郑消费->钢笔小李 生产->笔记本小李消费->笔记本小郑 生产->钢笔小郑消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小郑消费->钢笔小李 生产->笔记本小李消费->笔记本小郑消费->钢笔小郑 生产->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小郑消费->钢笔小李 生产->笔记本小李消费->笔记本小郑 生产->钢笔小郑消费->钢笔小李消费->笔记本小李 生产->笔记本小郑 生产->钢笔小郑消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小李消费->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->笔记本小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->钢笔小郑 生产->钢笔小李消费->笔记本小李 生产->笔记本小郑 生产->钢笔小李消费->钢笔小李 生产->笔记本小郑消费->笔记本小郑消费->笔记本小郑 生产->钢笔小李 生产->笔记本小郑消费->笔记本小郑 生产->钢笔小郑消费->钢笔小李消费->钢笔小李 生产->笔记本小郑 生产->钢笔小郑消费->钢笔小李 生产->笔记本小李消费->笔记本小郑 生产->钢笔小李消费->钢笔小李消费->笔记本小李 生产->笔记本Process finished with exit code 0
有上面结果可以看出产生了两个问题1.生产人和产物不对应,2.违背生产一个消费一个规则
解决 生产人和产物不对应问题
生产人和产物不对应是线程不同步导致,修改代码如下
class Info{ private String name; private String desc; public synchronized void set(String name,String desc){ this.name = name; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.desc = desc; System.err.println(name+" 生产->"+desc); } public synchronized void get(){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println(name+" 消费->"+desc); }}class Product implements Runnable{ private Info info; public Product(Info info){ this.info = info; } @Override public void run() { for(int i = 0;i<100;i++){ if(i % 2 == 0){ info.set("小郑","钢笔"); }else{ info.set("小李","笔记本"); } } }}class Consume implements Runnable{ private Info info; public Consume(Info info){ this.info = info; } @Override public void run() { for(int i = 0; i< 100;i++){ info.get(); } }}public class ProductCustumer { public static void main(String args[]){ Info info = new Info(); new Thread(new Product(info)).start(); new Thread(new Consume(info)).start(); }}
结果:小郑 生产->钢笔小李 生产->笔记本小郑 生产->钢笔小李 生产->笔记本小郑 生产->钢笔小李 生产->笔记本小郑 生产->钢笔小李 生产->笔记本小李 消费->笔记本小李 消费->笔记本小李 消费->笔记本小李 消费->笔记本小李 消费->笔记本小李 消费->笔记本小李 消费->笔记本
解决 违背生产一个消费一个规则
package a002;/** * Created by Administrator on 2018/2/23 0023. */class Info{ // falg true 可以生产,但是不能消费 false 可以消费,但不可以生产 private Boolean falg = true; //默认为true 先生产 private String name; private String desc; public synchronized void set(String name,String desc){ if(falg == false){ //等待消费 try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.desc = desc; System.err.println(name+" 生产->"+desc); //生产完成修改开关 this.falg = false; //唤醒生产线程 notify(); } public synchronized void get(){ if(falg){ //等待生产 try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println(name+" 消费->"+desc); falg = true; notify(); }}class Product implements Runnable{ private Info info; public Product(Info info){ this.info = info; } @Override public void run() { for(int i = 0;i<100;i++){ if(i % 2 == 0){ info.set("小郑","钢笔"); }else{ info.set("小李","笔记本"); } } }}class Consume implements Runnable{ private Info info; public Consume(Info info){ this.info = info; } @Override public void run() { for(int i = 0; i< 100;i++){ info.get(); } }}public class ProductCustumer { public static void main(String args[]){ Info info = new Info(); new Thread(new Product(info)).start(); new Thread(new Consume(info)).start(); }}
结果:小郑 生产->钢笔小郑 消费->钢笔小李 生产->笔记本小李 消费->笔记本小郑 生产->钢笔小郑 消费->钢笔小李 生产->笔记本小李 消费->笔记本小郑 生产->钢笔小郑 消费->钢笔小李 生产->笔记本小李 消费->笔记本小郑 生产->钢笔小郑 消费->钢笔小李 生产->笔记本小李 消费->笔记本