问题意义
生产者消费者问题是一个很经典的问题,通过解决此问题,能够学到多线程的的知识。
程序设计思路
在本程序中采用信号灯的方式,用Flag作为标志位,指示生产过程和消费过程是否结束。Flag为true时,生产者开始生产,消费者等待,Flag为false时,消费者开始消费,生产者等待。使用synchronize来锁定生产过程和消费过程,使得两个线程调用一个资源的时候能够有序进行。
程序清单
完整的程序有四个类文件组成,分别是Movie.java,Player.java, Watcher.java ,App.java。
Movie.java文件中源程序如下:
package com.bjsxt.thread.pro; /** * 一个场景,共同的资源 * 生产者消费者模式,信号灯法 * wait等待,它释放锁 * sleep不释放锁 * notify()唤醒线程 * @author Administrator * */ public class Movie { private String pic; private boolean Flag = true; //信号灯 //Flag为true时,生产者开始生产,消费者等待 //Flag为false时,消费者开始消费,生产者等待 public synchronized void play(String pic) { if(!Flag) { try { this.wait(); //等待 } catch (InterruptedException e) { e.printStackTrace(); } } //开始生产 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("生产了" + pic); //生产完毕 this.pic = pic; //通知消费者开始消费 this.notify(); Flag = false; } public synchronized void watch() { if(Flag) { try { this.wait(); //等待 } catch (InterruptedException e) { e.printStackTrace(); } } //开始生产 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //消费完毕 System.out.println("消费了" + pic); // this.notify(); this.Flag = true; } }Player.java文件中源程序如下:
package com.bjsxt.thread.pro; public class Player implements Runnable { private Movie m; public Player(Movie m) { super(); this.m = m; } @Override public void run() { for(int i=0;i<20;i++) { if(0 == i%2) { m.play("左青龙"); }else { m.play("右白虎"); } } } }
Watcher.java文件中源程序如下:
package com.bjsxt.thread.pro; public class Watcher implements Runnable { private Movie m; public Watcher(Movie m) { super(); this.m = m; } @Override public void run() { for(int i=0;i<20;i++) { m.watch(); } } }App.java文件中源程序如下:
package com.bjsxt.thread.pro; public class App { public static void main(String[] args) { //共同的资源 Movie m = new Movie(); //多线程 Player p = new Player(m); Watcher w = new Watcher(m); Thread t1 = new Thread(p); Thread t2 = new Thread(w); t1.start(); t2.start(); } }
运行结果
最终运行结果如下: