模拟生产者一边生产数据,消费者一边取出数据,
但以下代码会出现数据错位现象和重复生产,不符合我们的要求
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(); } }
奇数 这是奇数
偶数 这是偶数
奇数 这是奇数
偶数 这是偶数
奇数 这是奇数
偶数 这是偶数
奇数 这是奇数