一,介绍
生产者消费者模式,其实也是一种线程同步的机制,是利用线程间互斥的规则来达到,线程同步的,下面画个图来解释下这种机制
如下图:
解释一下:当生产者产生一个对象时,生产者就会等待,这个线程就会进入等待状态,然后唤醒消费者,消费者这个线程运行,消费者消费完成后,消费者这个
进程进入等待状态,这时生产者这个进程会被唤醒,生产者再次运行,这样周而复始,交替执行,下面看下一个Demo的代码
二,Demo案例
1.Move.java(相当于生产者生产的对象和消费者消费的对象,即两个线程共享的对象)
package com.geminno.thread;
public class Movie {
private String pic;
private boolean flag = true;
public Movie(String pic) {
super();
this.pic = pic;
}
public Movie() {
super();
// TODO Auto-generated constructor stub
}
public synchronized void play(String pic){
if(!flag){ // 如果flag 是false,停下不生产
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 开始生产
/*try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
System.out.println("我播放了电影=====>"+pic);
this.pic = pic;
//生产结束 ,叫醒消费者
this.notify();
//改变信号灯
this.flag = false;
}
public synchronized void watch(){
if(flag){//如果flag是true ,停止观看
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//开始观看
/*try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
System.out.println("我看了 --》"+pic);
//看完之后.叫醒生产者,开始生产
this.notifyAll();
//改变信号灯
this.flag = true;
}
}
2.生产者线程对象(Player.java)
package com.geminno.thread;
public class Player implements Runnable {
Movie m ;
public Player(Movie m) {
super();
this.m = m;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if(i % 2 == 0){
m.play("倚天屠龙记");
}else {
m.play("简爱");
}
}
}
}
3.消费者线程(watcher.java)
package com.geminno.thread;
public class Watcher implements Runnable{
Movie m ;
public Watcher(Movie m) {
super();
this.m = m;
}
@Override
public void run() {
for(int i=0;i<20;i++){
m.watch();
}
}
}
4.测试程序(App.java)
package com.geminno.thread;
public class App {
public static void main(String[] args) {
Movie m = new Movie();
Player player = new Player(m);
new Thread(player).start();
Watcher watcher = new Watcher(m);
new Thread(watcher).start();
}
}
5.打印结果
我们两个进程是交替执行,这样解决了线程不同步的问题了。另外,java1.5以后提供了新的等待唤醒机制,即Condition接口,使用方法是await()和signal方法
对应于wait和notify()方法。