生产者和消费者:public class Consumer extends Thread {   
    
    private String consumerName = null;   
       
    private StoreHouse storeHouse = null;   
  
    public Consumer(String consumerName, StoreHouse storeHouse) {   
        this.consumerName = consumerName;   
        this.storeHouse = storeHouse;   
    }   
       
    public void setConsumerName(String consumerName) {   
        this.consumerName = consumerName;   
    }   
       
    public String getConsumerName() {   
        return consumerName;   
    }   
       
    public synchronized void consumerProduct() {   
        while (true) {   
            System.out.println(getConsumerName() + " 消费了 " + storeHouse.pop());   
            try {   
                Thread.sleep(2000);   
            } catch (InterruptedException e) {   
                return;   
            } 
        }   
    }   
  
    public void run() {   
        consumerProduct();   
    }   
}public class Producer extends Thread {   

private static int i = 0;
    private String producerName = null;   
  
    private StoreHouse storeHouse = null;   
  
    public Producer(String producerName, StoreHouse storeHouse) {   
        this.producerName = producerName;   
        this.storeHouse = storeHouse;   
    }   
  
    public void setProducerName(String producerName) {   
        this.producerName = producerName;   
    }   
  
    public String getProducerName() {   
        return producerName;   
    }   
       
    public synchronized void produceProduct() {
        while (true) {   
            i++;   
            Product pro = new Product(i);   
            storeHouse.push(pro);   
            System.out.println(getProducerName() + " 生产了 " + pro);   
            try {   
                Thread.sleep(2000);   
            } catch (InterruptedException e) {   
                return;   
            }
        }   
    }   
  
    public void run() {   
        produceProduct();   
    }   
  
}  public class Product {   
  
    private int productId = 0;   
       
    public Product(int productId) {   
        this.productId = productId;   
    }   
  
    public int getProductId() {   
        return productId;   
    }   
  
    public String toString() {   
        return Integer.toString(productId);   
    }   
} public class StoreHouse {   
    private int base = 0;   
    private int top = 0;   
    private Product[] products = new Product[10];   
  
    public synchronized void push(Product product) {   
        while (top == products.length) { 
            try {   
                System.out.println("仓库已满,正等待消费...");   
                wait();   
            } catch (InterruptedException e) {   
                System.out.println("stop push product because other reasons");   
            }   
        }   
        products[top] = product;   
        top++;
        notifyAll();   
    }   
  
    public synchronized Product pop() {   
        Product pro = null;   
        while (top == base) {
            try {   
                System.out.println("仓库已空,正等待生产...");   
                wait();   
            } catch (InterruptedException e) {   
                System.out.println("stop push product because other reasons");   
            }   
        }   
        top--;   
        pro = products[top];   
        products[top] = null;
        notifyAll();   
        return pro;   
    }   
}public class Test {       StoreHouse storeHouse = new StoreHouse();   
    Producer producer1 = new Producer("生产者1", storeHouse);   
    Producer producer2 = new Producer("生产者2", storeHouse);   
    Producer producer3 = new Producer("生产者3", storeHouse);   
    Consumer comsumer1 = new Consumer("消费者1", storeHouse);
    Consumer comsumer2 = new Consumer("消费者2", storeHouse);
    public Test(){
        producer1.start();
        comsumer1.start();
        producer2.start();
        producer3.start();
        comsumer2.start();
    }
    public static void main(String[] args) {  
     new Test();
    }
}
输出如下:
生产者3 生产了 27
消费者2 消费了 27
生产者1 生产了 28
消费者1 消费了 28
生产者2 生产了 29
仓库已满,正等待消费...
生产者3 生产了 30
消费者2 消费了 29
仓库已满,正等待消费...
消费者1 消费了 30
生产者1 生产了 31
仓库已满,正等待消费...
仓库已满,正等待消费...
生产者3 生产了 33

消费者2 消费了 31
仓库已满,正等待消费...
仓库已满,正等待消费...
生产者3 生产了 34
仓库已满,正等待消费...

消费者1 消费了 33
仓库已满,正等待消费...
生产者1 生产了 35
仓库已满,正等待消费...不是已满了吗?怎么还可以生产?
我代码哪里有问题了?

解决方案 »

  1.   

    private static int i = 0;
    是这里除了问题,你的生产者和消费者线程的通信没有问题。只是你打印的product的名字有问题,你消费了一个product然后在生产新的product,使用构造函数product(i),这个i是一只递增的,所以最后通过toString给了你错误的幻想
    给你改了一下
    package day03;class Consumer extends Thread {   
        
        private String consumerName = null;   
           
        private StoreHouse storeHouse = null;   
      
        public Consumer(String consumerName, StoreHouse storeHouse) {   
            this.consumerName = consumerName;   
            this.storeHouse = storeHouse;   
        }   
           
        public void setConsumerName(String consumerName) {   
            this.consumerName = consumerName;   
        }   
           
        public String getConsumerName() {   
            return consumerName;   
        }   
           
        public synchronized void consumerProduct() {   
            while (true) {   
                System.out.println(getConsumerName() + " 消费了 " + storeHouse.pop());
                Producer.i--;
                try {   
                    Thread.sleep(2000);   
                } catch (InterruptedException e) {   
                    return;   
                } 
            }   
        }   
      
        public void run() {   
            consumerProduct();   
        }   
    }class Producer extends Thread {   
        
         static int i = 0;
        private String producerName = null;   
      
        private StoreHouse storeHouse = null;   
      
        public Producer(String producerName, StoreHouse storeHouse) {   
            this.producerName = producerName;   
            this.storeHouse = storeHouse;   
        }   
      
        public void setProducerName(String producerName) {   
            this.producerName = producerName;   
        }   
      
        public String getProducerName() {   
            return producerName;   
        }   
           
        public synchronized void produceProduct() {
            while (true) {   
                //i++;   
                //Product pro = new Product(i);   
                storeHouse.push(producerName);   
                   
                try {   
                    Thread.sleep(2000);   
                } catch (InterruptedException e) {   
                    return;   
                }
            }   
        }   
      
        public void run() {   
            produceProduct();   
        }   
      
    }  class Product {   
          
        private int productId = 0;   
           
        public Product(int productId) {   
            this.productId = productId;   
        }   
      
        public int getProductId() {   
            return productId;   
        }   
      
        public String toString() {   
            return Integer.toString(productId);   
        }   
    } class StoreHouse {   
        private int base = 0;   
        private int top = 0;   
        private Product[] products = new Product[10];   
      
        public synchronized void push(String producerName) {   
            while (top == products.length) { 
                try {
                
                    System.out.println("仓库已满,正等待消费...");   
                    this.wait();   
                } catch (InterruptedException e) {   
                    System.out.println("stop push product because other reasons");   
                }   
            }   
            Product product=new Product(top);
            products[top] = product;  
            System.out.println(producerName + " 生产了 " + product);
            top++;
            notifyAll();   
        }   
      
        public synchronized Product pop() {   
            Product pro = null;   
            while (top == base) {
                try {   
                    System.out.println("仓库已空,正等待生产...");   
                    wait();   
                } catch (InterruptedException e) {   
                    System.out.println("stop push product because other reasons");   
                }   
            }   
            top--;   
            pro = products[top];   
            products[top] = null;
            notifyAll();   
            return pro;   
        }   
    }public class Test {       StoreHouse storeHouse = new StoreHouse();   
        Producer producer1 = new Producer("生产者1", storeHouse);   
        Producer producer2 = new Producer("生产者2", storeHouse);   
        Producer producer3 = new Producer("生产者3", storeHouse);   
        Consumer comsumer1 = new Consumer("消费者1", storeHouse);
        Consumer comsumer2 = new Consumer("消费者2", storeHouse);
        public Test(){
            producer1.start();
            comsumer1.start();
            producer2.start();
            producer3.start();
            comsumer2.start();
        }
        public static void main(String[] args) {  
            new Test();
        }
    }重点改了public synchronized void push(String producerName)方法
    测试结果
    消费者2 消费了 9
    生产者2 生产了 9
    消费者1 消费了 9
    生产者3 生产了 9
    仓库已满,正等待消费...
    仓库已满,正等待消费...
    消费者2 消费了 9
    生产者2 生产了 9
    仓库已满,正等待消费...
    消费者1 消费了 9
    生产者1 生产了 9
    仓库已满,正等待消费...
    仓库已满,正等待消费...
    消费者2 消费了 9
    生产者2 生产了 9
    仓库已满,正等待消费...
    仓库已满,正等待消费...
    消费者1 消费了 9
    生产者1 生产了 9
    仓库已满,正等待消费...
    仓库已满,正等待消费...
    消费者2 消费了 9
    生产者2 生产了 9
    仓库已满,正等待消费...
    仓库已满,正等待消费...
    消费者1 消费了 9
    生产者1 生产了 9
    仓库已满,正等待消费...
      

  2.   

    把生产、消费、打印移到StoreHouse里面就没问题了。不过还是不明白上面的为什么会错:
    仓库已满,正等待消费...
    仓库已满,正等待消费...
    生产者3 生产了 33
    消费者2 消费了 31
    仓库已满,正等待消费...
    仓库已满,正等待消费...
    生产者3 生产了 34
    仓库已满,正等待消费...
    消费者1 消费了 33
    仓库都满了,为什么还是会生产了34,而不是先消费了33,再生产34呢?
      

  3.   

    你把push和pop方法里的wait()改为this.wait()
    刚才没发现
      

  4.   

    把所有输出放在 notify之前。
      

  5.   

    顺便说一下,楼主的写法有点问题,最后会变成长度为1的一个FIFO。今天心情不太好,只是稍改了一下。 class Consumer extends Thread {   
        
        private String consumerName = null;   
           
        private StoreHouse storeHouse = null;   
      
        public Consumer(String consumerName, StoreHouse storeHouse) {   
            this.consumerName = consumerName;   
            this.storeHouse = storeHouse;   
        }   
           
        public void setConsumerName(String consumerName) {   
            this.consumerName = consumerName;   
        }   
           
        public String getConsumerName() {   
            return consumerName;   
        }   
           
        public synchronized void consumerProduct() {   
            while (true) {   
                Product p = storeHouse.pop();
                //System.out.println(getConsumerName() + " 消费了 " + p);   
                storeHouse.print();
                try {   
                    Thread.sleep(3000);   
                } catch (InterruptedException e) {   
                    return;   
                } 
            }   
        }   
      
        public void run() {   
            consumerProduct();   
        }   
    } class Producer extends Thread {   
        
        private static int i = 0;
        private String producerName = null;   
      
        private StoreHouse storeHouse = null;   
      
        public Producer(String producerName, StoreHouse storeHouse) {   
            this.producerName = producerName;   
            this.storeHouse = storeHouse;   
        }   
      
        public void setProducerName(String producerName) {   
            this.producerName = producerName;   
        }   
      
        public String getProducerName() {   
            return producerName;   
        }   
           
        public synchronized void produceProduct() {
            while (true) {   
                i++;   
                Product pro = new Product(i);   
                storeHouse.push(pro);   
                //System.out.println(getProducerName() + " 生产了 " + pro);   
                storeHouse.print();
                try {   
                    Thread.sleep(1000);   
                } catch (InterruptedException e) {   
                    e.printStackTrace();
                    return;   
                }
            }   
        }   
      
        public void run() {   
            produceProduct();   
        }   
      
    }   class Product {   
          
        private int productId = 0;   
           
        public Product(int productId) {   
            this.productId = productId;   
        }   
      
        public synchronized int getProductId() {   
            return productId;   
        }   
      
        public String toString() {   
            return Integer.toString(productId);   
        }   
    }  class StoreHouse {   
        private int pushPoint = 0;   
        private int popPoint = 0; 
        private int size = 0; 
        
        private final int fifoSize = 2;
        private Product[] products = new Product[10];   
      
        public synchronized void push(Product product) {   
            while (size == fifoSize) { 
                try {   
                    System.out.println("仓库已满,正等待消费...");   
                    wait();   
                } catch (InterruptedException e) {   
                    System.out.println("stop push product because other reasons");   
                }   
            }   
            System.out.println("可以生产");
            products[pushPoint] = product;   
            System.out.println("生产了" +  product);
            pushPoint = (pushPoint + 1) % fifoSize;
            size++;
            System.out.print("########");
            print();
            this.notifyAll();
        }   
      
        public synchronized Product pop() {   
            Product pro = null;   
            while (size == 0) {
                try {   
                    System.out.println("仓库已空,正等待生产...");   
                    wait();   
                } catch (InterruptedException e) {   
                    System.out.println("stop push product because other reasons");   
                }   
            }   
            System.out.println("可以消费");
            pro = products[popPoint];   
            System.out.println("消费了"+ pro);
            popPoint = (popPoint + 1) % fifoSize;
            size--;
            System.out.print("&&&&&&&&&&");
            print();
            this.notifyAll();
            return pro;   
        }   
        
        public synchronized void print(){
            System.out.println("pPonit = " + this.pushPoint + ", cPoint =" + this.popPoint + ", size is " + this.size);
        }
    }public class Test {       StoreHouse storeHouse = new StoreHouse();   
        Producer producer1 = new Producer("生产者1", storeHouse);   
        Producer producer2 = new Producer("生产者2", storeHouse);   
        Producer producer3 = new Producer("生产者3", storeHouse);  
        
        Consumer comsumer1 = new Consumer("消费者1", storeHouse);
        Consumer comsumer2 = new Consumer("消费者2", storeHouse);
        public Test(){
            producer1.start();
            comsumer1.start();
            producer2.start();
            producer3.start();
            comsumer2.start();
        }
        public static void main(String[] args) {  
            new Test();
        }
    }
      

  6.   

    打印次序不对是因为你只把存和取做了同步,而打印没有跟存取脱离的还有,produceProduct 和 consumerProduct 的synchronized 没有意义啊,只有线程自己去调用的,不需要同步