/*
生产者消费者模式:
1.分清哪些资源是共享的。比如生产消费的烤鸭数量,对输出结果写入到的目标文件也是共享的。
不同线程的执行的程序是不一样的,定义在不同的方法中,这些方法就需要同步并且相互之间可以通信;
2.分别创建不同的线程,将需要执行的程序或者方法 封装到重写的run方法之中;
3.创建主类并实例化相关对象,启动线程执行程序。
*/
/*
baked duck multi-thread demo
*/
//create the duck resource
import java.io.*;
class Resource
{
private int num = 0;
private FileOutputStream fos;
boolean flag = false;
Resource(int num,FileOutputStream fos){
this.num = num;
this.fos = fos;
}
/* this sentence cannnot exist lonely,it must be written in a function
try{
FileOutputStream fos = new FileOutputStream("DuckConsumptionDemo.txt",true);
}catch(Exception e){
e.printStackTrace();
}
*/
public synchronized void produce(){
/*
try{
System.setOut(new PrintStream(fos));
}catch(Exception e){
e.printStackTrace();
}*/
while(flag) //循环判断避免还没消费就继续生产,所以对内部被唤醒的线程重新进行判断是否需要休眠
try{
this.wait(); //lock the thread itself
//num++; //num add 1 after unlock
}catch(InterruptedException e){
e.printStackTrace();
}
num++;
System.setOut(new PrintStream(fos)); //the writting destination must be shared
System.out.println(Thread.currentThread().getName()+"produce baked duck:"+num);
flag = true;
notifyAll(); //多个线程,如果唤醒同性质线程没有意义,所以要用while循环判断
}
public synchronized void consume(){
/*
try{
System.setOut(new PrintStream(fos));
}catch(Exception e){
e.printStackTrace();
}*/
while(!flag) //避免唤醒同性质线程还没生产就重复消费,所以对内部被唤醒的线程重新进行判断是否需要休眠
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.setOut(new PrintStream(fos));
System.out.println(Thread.currentThread().getName()+"consume baked duck:"+num);
flag = false;
notifyAll();
}
}
//create produce thread
class Produce implements Runnable{
private Resource r;
public Produce(Resource r){
this.r = r;
}
public void run(){
while(true){
r.produce();
}
}
}
//create consume thread
class Consume implements Runnable{
private Resource r;
public Consume(Resource r){
this.r = r;
}
public void run(){
while(true){
r.consume();
}
}
}
//create the real production line
class DuckConsumptionDemo{
public static void main(String[] args){
try{
FileOutputStream fos = new FileOutputStream("DuckConsumptionDemo.txt");
Resource r = new Resource(1,fos); //produce from the first duck
Produce produce = new Produce(r);
Consume consume = new Consume(r);
Thread t1 = new Thread(produce);
Thread t2 = new Thread(produce);
Thread t3 = new Thread(consume);
Thread t4 = new Thread(consume);
t1.start();
t2.start();
t3.start();
t4.start();
}catch(Exception e){
e.printStackTrace();
}
}
}
|
|