解决方案 »

  1.   

    public class ProducerConsumer {
    public static void main(String[] args) {
    Basket basket = new Basket();
    Producer producer = new Producer(basket);
    Consumer consumer = new Consumer(basket);
    Thread thread1 = new Thread(producer);
    Thread thread2 = new Thread(consumer);
    thread1.start();
    thread2.start();
    }
    }class Bread {
    private String producer; Bread(String producer) {
    this.producer = producer;
    } public String toString() {
    return producer;
    }
    }class Basket {
    private int index = 0;
    Bread[] bread = new Bread[6]; public synchronized void push(Bread b) {
    System.out.println("生产前篮子里面包数:" + index);
    while (index == bread.length) {
    System.out.println("篮子里满了,开始等待!");
    try {
    this.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    bread[index] = b;
    index++;
    this.notify();
    } public synchronized Bread pop() {
    System.out.println("消费前篮子里面包数为:" + index);
    while (index == 0) {
    System.out.println("篮子里为空,开始等待!");
    try {
    this.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    index--;
    this.notify();
    return bread[index];
    }
    }class Producer implements Runnable {
    private Basket basket; public Producer(Basket basket) {
    this.basket = basket;
    } public void run() {
    for (int i = 0; i < 10; i++) {
    Bread bread = new Bread("第" + i + "个面包");
    basket.push(bread);
    System.out.println("生产了: " + bread);
    // try {
    // Thread.sleep(1);
    // } catch (InterruptedException e) {
    // e.printStackTrace();
    // }
    } }
    }class Consumer implements Runnable {
    private Basket basket; public Consumer(Basket basket) {
    this.basket = basket;
    } public void run() {
    for (int i = 0; i < 10; i++) {
    System.out.println("消费了:" + basket.pop());
    // try {
    // Thread.sleep(1);
    // } catch (InterruptedException e) {
    // e.printStackTrace();
    // }
    }
    }
    }
      

  2.   

    Thread这方面一直是软肋。学习了,多谢分享!!
      

  3.   

    上面程序存在的bug是:
    假设生产者生产满了篮子,然后就会处于休眠转台,消费者一直在篮子里取面包,等到面包完了以后就处于休眠状态。这时候就是消费者和生产者都处于休眠状态,这个生产消费者系统将不会继续用作。所以要保证系统的正常运行,至少应该在消费者消费完篮子里面的东西时,自我休眠前唤醒生产者来工作。
      

  4.   

    Thread.sleep(1); 在生产者和消费者中都有这个,是不对的,生产者里这个时间应该是生产一个面包所需要的时间,这个是固定的,为1毫秒也可以,但是在消费者里,消费者来的时间间隔应该是不固定的,随机的,在这里应该模拟随机数作为休眠的时间,这样你就可以得到模拟的真实情况了。
    修改后:
    生产者:Thread.sleep(100);
    消费者:
    //假设消费者来的时间间隔最小为1,最大为1000,产生随机数
    //取当前时间的毫秒,取模
    long lTime=System.currentTimeMillis();
    lTime=lTime/1000 + 1;
    Thread.sleep(lTime); 修改后运行结果:
    run:
    生产前篮子里面包数:0
    生产了: 第0个面包
    消费前篮子里面包数为:1
    消费了:第0个面包
    生产前篮子里面包数:0
    生产了: 第1个面包
    生产前篮子里面包数:1
    生产了: 第2个面包
    生产前篮子里面包数:2
    生产了: 第3个面包
    生产前篮子里面包数:3
    生产了: 第4个面包
    生产前篮子里面包数:4
    生产了: 第5个面包
    生产前篮子里面包数:5
    生产了: 第6个面包
    生产前篮子里面包数:6
    篮子里满了,开始等待!
    加上4楼的互相唤醒机制,就ok了........
      

  5.   

    仔细看了下,你的程序问题还挺多的,首先,消费者来的间隔时间不确定,其次,消费者来的多了,很可能要排队,
    重新修改了程序package test;import java.util.ArrayList;
    import java.util.List;public class ProducerConsumer {    private Basket basket=new Basket();    public void begin() {
            Producer producer = new Producer();
            Consumer consumer = new Consumer();
            Thread thread1 = new Thread(producer);
            Thread thread2 = new Thread(consumer);
            thread1.start();
            thread2.start();
        }    class Bread {        private String producer;        Bread(String producer) {
                this.producer = producer;
            }        @Override
            public String toString() {
                return producer;
            }
        }    class Custom {        private String custom;        Custom(String custom) {
                this.custom = custom;
            }        @Override
            public String toString() {
                return custom;
            }
        }    class Basket {        List<Bread> breadList = new ArrayList<Bread>();        public void push(Bread b) {            if (breadList.size() > 5) {
                    System.out.println("篮子里满了,请等待!");
                } else {
                    breadList.add(b);
                    System.out.println("生产后篮子里面包数:" + breadList.size());
                }
            }        public Bread pop() {
                Bread bread = null;
                if (breadList.size() == 0) {
                    System.out.println("篮子里为空,请等待!");
                } else {
                    bread = breadList.get(0);
                    breadList.remove(0);
                    System.out.println("消费后篮子里面包数为:" + breadList.size());
                }
                return bread;
            }
        }    class Producer implements Runnable {        public Producer() {
            }        public void run() {
                for (int i = 0; i < 100; i++) {
                    while (basket.breadList.size() > 5) {
                        try {
                            //如果篮子满了等待时间
                            System.out.println("篮子里满了,生产开始等待!");
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    Bread bread = new Bread("第" + i + "个面包");
                    basket.push(bread);
                    System.out.println("生产了: " + bread);
                    try {
                        //生产面包所需时间
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }    class Consumer implements Runnable {        public Consumer() {
            }        public void run() {
                for (int i = 0; i < 100; i++) {
                    while (basket.breadList.size() == 0) {
                        try {
                            //如果篮子空了等待时间
                            System.out.println("篮子里空了,消费者开始等待!");
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("消费了:" + basket.pop());
                    try {
                        //假设消费者来的时间间隔最小为1,最大为200,产生随机数
                        //取当前时间的毫秒,取模
                        long lTime = System.currentTimeMillis();
                        lTime = lTime % 300 + 1;
                        Thread.sleep(lTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    程序main类:package test;public class Main {    /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            // TODO code application logic here
            ProducerConsumer producer= new ProducerConsumer();
            producer.begin();
        }}
    调整不同的生产时间和消费者产生时间,会看到生产者等待和消费者等待的不同情况。
    运行结果:
    run:
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第0个面包
    消费后篮子里面包数为:0
    消费了:第0个面包
    生产后篮子里面包数:1
    生产了: 第1个面包
    消费后篮子里面包数为:0
    消费了:第1个面包
    生产后篮子里面包数:1
    生产了: 第2个面包
    消费后篮子里面包数为:0
    消费了:第2个面包
    生产后篮子里面包数:1
    生产了: 第3个面包
    消费后篮子里面包数为:0
    消费了:第3个面包
    生产后篮子里面包数:1
    生产了: 第4个面包
    消费后篮子里面包数为:0
    消费了:第4个面包
    生产后篮子里面包数:1
    生产了: 第5个面包
    消费后篮子里面包数为:0
    消费了:第5个面包
    生产后篮子里面包数:1
    生产了: 第6个面包
    消费后篮子里面包数为:0
    消费了:第6个面包
    生产后篮子里面包数:1
    生产了: 第7个面包
    消费后篮子里面包数为:0
    消费了:第7个面包
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第8个面包
    消费后篮子里面包数为:0
    消费了:第8个面包
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第9个面包
    消费后篮子里面包数为:0
    消费了:第9个面包
    生产后篮子里面包数:1
    生产了: 第10个面包
    消费后篮子里面包数为:0
    消费了:第10个面包
    生产后篮子里面包数:1
    生产了: 第11个面包
    消费后篮子里面包数为:0
    消费了:第11个面包
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第12个面包
    消费后篮子里面包数为:0
    消费了:第12个面包
    生产后篮子里面包数:1
    生产了: 第13个面包
    消费后篮子里面包数为:0
    消费了:第13个面包
    生产后篮子里面包数:1
    生产了: 第14个面包
    生产后篮子里面包数:2
    生产了: 第15个面包
    消费后篮子里面包数为:1
    消费了:第14个面包
    生产后篮子里面包数:2
    生产了: 第16个面包
    消费后篮子里面包数为:1
    消费了:第15个面包
    消费后篮子里面包数为:0
    消费了:第16个面包
    生产后篮子里面包数:1
    生产了: 第17个面包
    生产后篮子里面包数:2
    生产了: 第18个面包
    消费后篮子里面包数为:1
    消费了:第17个面包
    生产后篮子里面包数:2
    生产了: 第19个面包
    消费后篮子里面包数为:1
    消费了:第18个面包
    消费后篮子里面包数为:0
    消费了:第19个面包
    生产后篮子里面包数:1
    生产了: 第20个面包
    消费后篮子里面包数为:0
    消费了:第20个面包
    生产后篮子里面包数:1
    生产了: 第21个面包
    消费后篮子里面包数为:0
    消费了:第21个面包
    生产后篮子里面包数:1
    生产了: 第22个面包
    消费后篮子里面包数为:0
    消费了:第22个面包
    生产后篮子里面包数:1
    生产了: 第23个面包
    消费后篮子里面包数为:0
    消费了:第23个面包
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第24个面包
    消费后篮子里面包数为:0
    消费了:第24个面包
    生产后篮子里面包数:1
    生产了: 第25个面包
    消费后篮子里面包数为:0
    消费了:第25个面包
    生产后篮子里面包数:1
    生产了: 第26个面包
    消费后篮子里面包数为:0
    消费了:第26个面包
    生产后篮子里面包数:1
    生产了: 第27个面包
    生产后篮子里面包数:2
    生产了: 第28个面包
    消费后篮子里面包数为:1
    消费了:第27个面包
    消费后篮子里面包数为:0
    消费了:第28个面包
    生产后篮子里面包数:1
    生产了: 第29个面包
    消费后篮子里面包数为:0
    消费了:第29个面包
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第30个面包
    消费后篮子里面包数为:0
    消费了:第30个面包
    生产后篮子里面包数:1
    生产了: 第31个面包
    消费后篮子里面包数为:0
    消费了:第31个面包
    生产后篮子里面包数:1
    生产了: 第32个面包
    消费后篮子里面包数为:0
    消费了:第32个面包
    生产后篮子里面包数:1
    生产了: 第33个面包
    消费后篮子里面包数为:0
    消费了:第33个面包
    生产后篮子里面包数:1
    生产了: 第34个面包
    消费后篮子里面包数为:0
    消费了:第34个面包
    生产后篮子里面包数:1
    生产了: 第35个面包
    消费后篮子里面包数为:0
    消费了:第35个面包
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第36个面包
    消费后篮子里面包数为:0
    消费了:第36个面包
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第37个面包
    消费后篮子里面包数为:0
    消费了:第37个面包
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第38个面包
    消费后篮子里面包数为:0
    消费了:第38个面包
    篮子里空了,消费者开始等待!
    生产后篮子里面包数:1
    生产了: 第39个面包
    消费后篮子里面包数为:0
    消费了:第39个面包
    篮子里空了,消费者开始等待!
    篮子里空了,消费者开始等待!
      

  6.   

    上面的例子还是有问题,重新修改下,客户可以购买最多3个面包:import java.util.ArrayList;
    import java.util.List;/**
     *
     * @author pantianzhu
     */
    public class ProducerConsumer {    private Basket basket=new Basket();    public void begin() {
            Producer producer = new Producer();
            Consumer consumer = new Consumer();
            Thread thread1 = new Thread(producer);
            Thread thread2 = new Thread(consumer);
            Thread thread3 = new Thread(basket);
            thread1.start();
            thread2.start();
            thread3.run();
        }    class Bread {        private String producer;        Bread(String producer) {
                this.producer = producer;
            }        @Override
            public String toString() {
                return producer;
            }
        }    class Custom {        private String custom;
            private int breads;        Custom(String custom,int breads) {
                this.custom = custom;
                this.breads = breads;
            }        @Override
            public String toString() {
                return custom;
            }
        }    class Basket implements Runnable {        List<Bread> breadList = new ArrayList<Bread>();
            List<Custom> custList = new ArrayList<Custom>();        public void push(Bread b) {            if (breadList.size() > 5) {
                    System.out.println("篮子里满了,请等待!");
                } else {
                    breadList.add(b);
                    System.out.println("生产后篮子里面包数:" + breadList.size());
                }
            }        public Bread pop() {
                Bread bread = null;
                if (breadList.size() == 0) {
                    System.out.println("篮子里为空,请等待!");
                } else {
                    bread = breadList.get(0);
                    breadList.remove(0);
    //                System.out.println("消费后篮子里面包数为:" + breadList.size()+",排队的客户数"+custList.size());
                }
                return bread;
            }        public void run() {
                while(true){
                    if(custList.size()>0){
                        Custom custom=custList.get(0);
                        for(int i=0;i<custom.breads;i++){
                            boolean succ=false;
                            while(!succ){
                                Bread bread = pop();
                                if (bread != null) {
                                    System.out.println(custList.get(0) + "消费了" + bread.toString());
                                    succ=true;
                                }else{
                                    try {
                                        Thread.sleep(50);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                        
                        custList.remove(0);
                        System.out.println("消费后篮子里面包数为:" + breadList.size()+",排队的客户数"+custList.size());
                    }
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }    class Producer implements Runnable {        public Producer() {
            }        public void run() {
                for (int i = 0; i < 100; i++) {
                    while (basket.breadList.size() > 5) {
                        try {
                            //如果篮子满了等待时间
                            System.out.println("篮子里满了,生产开始等待!");
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    Bread bread = new Bread("第" + i + "个面包");
                    basket.push(bread);
                    System.out.println("生产了: " + bread);
                    try {
                        //生产面包所需时间
                        Thread.sleep(150);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }    class Consumer implements Runnable {        public Consumer() {
            }        public void run() {
                for (int i = 0; i < 20; i++) {
                    long lbuys;
                    int buys=0;
                    //假设消费者购买数最小为1,最大为3,产生随机数
                    //取当前时间的毫秒,取模
                    lbuys = System.currentTimeMillis();
                    buys = (int)(lbuys % 3) + 1;
                    Custom custom = new Custom("第" + i + "个客户",buys);
                    basket.custList.add(custom);
                    System.out.println("产生了" +custom.toString()+",要购买"+custom.breads+"个面包");
                    try {
                        //假设消费者来的时间间隔最小为1,最大为200,产生随机数
                        //取当前时间的毫秒,取模
                        long lTime = System.currentTimeMillis();
                        lTime = lTime % 400 + 1;
                        Thread.sleep(lTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }run:
    产生了第0个客户,要购买2个面包
    生产后篮子里面包数:1
    生产了: 第0个面包
    第0个客户消费了第0个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第1个面包
    第0个客户消费了第1个面包
    消费后篮子里面包数为:0,排队的客户数0
    生产后篮子里面包数:1
    生产了: 第2个面包
    产生了第1个客户,要购买2个面包
    第1个客户消费了第2个面包
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第3个面包
    第1个客户消费了第3个面包
    消费后篮子里面包数为:0,排队的客户数0
    生产后篮子里面包数:1
    生产了: 第4个面包
    产生了第2个客户,要购买3个面包
    第2个客户消费了第4个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第5个面包
    第2个客户消费了第5个面包
    篮子里为空,请等待!
    产生了第3个客户,要购买1个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第6个面包
    第2个客户消费了第6个面包
    消费后篮子里面包数为:0,排队的客户数1
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第7个面包
    第3个客户消费了第7个面包
    消费后篮子里面包数为:0,排队的客户数0
    产生了第4个客户,要购买3个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第8个面包
    第4个客户消费了第8个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    篮子里为空,请等待!
    产生了第5个客户,要购买3个面包
    产生了第6个客户,要购买2个面包
    生产后篮子里面包数:1
    生产了: 第9个面包
    第4个客户消费了第9个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    产生了第7个客户,要购买1个面包
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第10个面包
    第4个客户消费了第10个面包
    消费后篮子里面包数为:0,排队的客户数3
    产生了第8个客户,要购买2个面包
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第11个面包
    第5个客户消费了第11个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第12个面包
    第5个客户消费了第12个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    篮子里为空,请等待!
    产生了第9个客户,要购买1个面包
    生产后篮子里面包数:1
    生产了: 第13个面包
    第5个客户消费了第13个面包
    消费后篮子里面包数为:0,排队的客户数4
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第14个面包
    第6个客户消费了第14个面包
    篮子里为空,请等待!
    产生了第10个客户,要购买3个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第15个面包
    第6个客户消费了第15个面包
    消费后篮子里面包数为:0,排队的客户数4
    产生了第11个客户,要购买3个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第16个面包
    第7个客户消费了第16个面包
    消费后篮子里面包数为:0,排队的客户数4
    篮子里为空,请等待!
    产生了第12个客户,要购买3个面包
    篮子里为空,请等待!
    产生了第13个客户,要购买2个面包
    生产后篮子里面包数:1
    生产了: 第17个面包
    第8个客户消费了第17个面包
    篮子里为空,请等待!
    产生了第14个客户,要购买3个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    产生了第15个客户,要购买1个面包
    生产后篮子里面包数:1
    生产了: 第18个面包
    第8个客户消费了第18个面包
    消费后篮子里面包数为:0,排队的客户数7
    篮子里为空,请等待!
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第19个面包
    第9个客户消费了第19个面包
    消费后篮子里面包数为:0,排队的客户数6
    产生了第16个客户,要购买1个面包
    篮子里为空,请等待!
    产生了第17个客户,要购买3个面包
    篮子里为空,请等待!
    产生了第18个客户,要购买1个面包
    生产后篮子里面包数:1
    生产了: 第20个面包
    第10个客户消费了第20个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
    产生了第19个客户,要购买3个面包
    篮子里为空,请等待!
    生产后篮子里面包数:1
    生产了: 第21个面包
    第10个客户消费了第21个面包
    篮子里为空,请等待!
    篮子里为空,请等待!
      

  7.   

    package JavaThread;public class ProducerConsumer {
    public static void main(String[] args) {
    Basket basket = new Basket();
    Producer producer = new Producer(basket);
    Consumer consumer = new Consumer(basket);
    Thread thread1 = new Thread(producer);
    Thread thread2 = new Thread(consumer);
    thread1.start();
    thread2.start();
    }
    }class Bread {
     private String producer;
     Bread(String producer) {
     this.producer = producer;
     }
     
     public String toString() {
     return producer;
     }
    }class Basket {
    private int index = 0;
    Bread[] bread = new Bread[6];

    public synchronized void push(Bread b) {
    System.out.println("生产前篮子里面包数:" + index);
    while(index == bread.length) {
    System.out.println("篮子里满了,开始等待!");
    try {
    this.wait();
    } catch(InterruptedException e) {
    e.printStackTrace();
    }
    }
    this.notify();
    bread[index] = b;
    //System.out.println("生产了:" + bread[index]);
    index++;
    }

    public synchronized Bread pop() {
    System.out.println("消费前篮子里面包数为:" + index);
    while(index == 0) {
    System.out.println("篮子里为空,开始等待!");
    try {
    this.wait();
    } catch(InterruptedException e) {
    e.printStackTrace();
    }
    }
    index--;
    return bread[index];
    }
    }class Producer implements Runnable {
    private Basket basket;

    public Producer(Basket basket) {
    this.basket = basket;
    }

    public void run() {
    for(int i=0; i<10; i++) {
    Bread bread = new Bread("第" + i + "个面包");
    basket.push(bread);
    System.out.println("生产了: " + bread);
    try {
    Thread.sleep(1);
    } catch(InterruptedException e) {
    e.printStackTrace();
    }
    }

     
    }
    }class Consumer implements Runnable {
    private Basket basket;

    public Consumer(Basket basket) {
    this.basket = basket;
    }

    public void run() {
    for(int i=0; i<10; i++) {
    System.out.println("消费了:" + basket.pop());
    try {
    Thread.sleep(1);
    } catch(InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }上面是楼主的程序,楼主开启了两个线程,就出现了死等待
    解决办法:
    第一种:把while循化,给我if判断。
    第二种:把this.notify改为this.notifyAll()