//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();
}
}
}