在说生产者消费者模式之前,我觉得有必要理解一下 Obj.wait(),与Obj.notify()方法。wait()方法是指在持有对象锁的线程调用此方法时,会释放对象锁,同时休眠本线程。notify()方法是持有相同的对象锁来唤醒休眠的线程,使其具有抢占cpu的资格。可以理解同步方法,同步方法的对象锁就是谁调用这个方法,这个对象就是对象锁。
根据李兴华老师的视频讲解,建立一个生产者类,一个消费者类,还有一个Info类,贴上代码:
1.生产者类
package com.company; /** * Created by Administrator on 2016/8/30. */ public class Productor implements Runnable { private Info info; public Productor(Info info) { this.info = info; } @Override public void run() { for (int i=0;i<50;i++) { if (i%2==0) { // info.setTitle("陶帅"); // info.setContent("一个帅哥"); // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } info.set("陶帅","一个帅哥"); }else { // info.setTitle("可爱的动物"); // info.setContent("草泥马"); info.set("可爱的动物","草泥马"); // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } } } } }
2.消费者类
package com.company; /** * Created by Administrator on 2016/8/30. */ 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(100); } catch (InterruptedException e) { e.printStackTrace(); } info.get(); } } }
3.Info类(重点)
package com.company; /** * Created by Administrator on 2016/8/30. */ public class Info { private String Title; private String content; private boolean flag=true;//true表示可以生产不能取走消费,false相反 public synchronized void set(String Titile,String content){ if (!flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.Title=Titile; this.content=content; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } flag=false; notify(); } public synchronized void get(){ if (flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.Title+"------->"+this.content); flag=true; notify(); } // public String getTitle() { // return Title; // } // // public void setTitle(String title) { // Title = title; // } // // public String getContent() { // return content; // } // // public void setContent(String content) { // this.content = content; // } }
4.测试类
package com.company; public class Main { public static void main(String[] args) { Info info=new Info(); Productor p=new Productor(info); Consumer c=new Consumer(info); new Thread(p).start(); new Thread(c).start(); } }
总结分析:生产者和消费者两个线程同时抢占CPU,假如消费者先抢到,此时调用get()方法即消费取走,但是此时flag为true,因此会进入wait()方法,所以此时只能是生产者抢占到CPU,根据生产者调用set()方法,生产后执行
flag=false; notify();
此时生产者和消费者所在的两个线程又站在同一起跑线上了,继续CPU争夺战。如果不幸的消费者又没有抢过生产者,生产者继续执行set();此时flag已经是false了,根据代码
if (!flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } }
所以生产者只能乖乖的wait();CPU回到消费者这里,循环往复,模式就出来了,完美!
时间: 2024-10-12 23:46:14