A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

/*
生产者消费者模式:
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();
                }
        }
}



0 个回复

您需要登录后才可以回帖 登录 | 加入黑马