想模拟一段生产者消费者问题。
利用一个栈来模拟一个容器来装商品,然后里面定义一个6位的数组,用index来标记
程序如下
public class ProducerConsumer { /**
 * @param args
 */ public static void main(String[] args) {
// TODO Auto-generated method stub
Container contain = new Container();
Producer pro = new Producer(contain);
Consumer con = new Consumer(contain);
new Thread(con).start();
new Thread(pro).start(); }}class Item {
int id; Item(int id) {
this.id = id;
}
public String toString() {
return  String.valueOf(id) ;
}}class Container {
int index = 0;
Item[] items = new Item[6]; public synchronized void push(Item item) {
while (index == items.length) {
try {
System.out.println("满了!!!!!!!!!!!!!!!!!!!!!!" );
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} items[index] = item;
index++;
notifyAll(); } public synchronized Item pop() { while (index == 0) { try {
System.out.println("空了!!!!!!!!!!!!!!!!!!!!!!!!!!" ); wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} index--;
notifyAll();
return items[index]; }}class Producer implements Runnable {
Container contain = null; Producer(Container contain) {
this.contain = contain;
} public void run() { for (int i = 0; i <= 10; i++) {
Item it = new Item(i);
contain.push(it);
// System.out.println("生产了第" + it + "个商品   ");
 System.out.println("生产了第" + it + "个商品   "+"现在还有" +
 contain.index + "个商品");
} }}class Consumer implements Runnable {
Container contain = null; Consumer(Container contain) {
this.contain = contain;
} public void run() { for (int i = 0; i <= 10; i++) {
Item it=contain.pop();
// System.out.println("消费了第" + it + "个商品   ");
 System.out.println("消费了第" + it + "个商品   "+"现在还有" +
 contain.index + "个商品");
} }
}
但是结果如下:
空了!!!!!!!!!!!!!!!!!!!!!!!!!!
生产了第0个商品 现在还有0个商品
生产了第1个商品 现在还有1个商品
生产了第2个商品 现在还有2个商品
消费了第0个商品 现在还有0个商品
消费了第3个商品 现在还有2个商品
消费了第2个商品 现在还有1个商品
消费了第1个商品 现在还有0个商品
空了!!!!!!!!!!!!!!!!!!!!!!!!!!
生产了第3个商品 现在还有3个商品
生产了第4个商品 现在还有1个商品
消费了第4个商品 现在还有0个商品
消费了第5个商品 现在还有0个商品
空了!!!!!!!!!!!!!!!!!!!!!!!!!!
生产了第5个商品 现在还有1个商品
生产了第6个商品 现在还有1个商品
生产了第7个商品 现在还有1个商品
消费了第6个商品 现在还有0个商品
消费了第8个商品 现在还有1个商品
生产了第8个商品 现在还有2个商品
生产了第9个商品 现在还有1个商品
消费了第7个商品 现在还有0个商品
消费了第10个商品 现在还有1个商品
生产了第10个商品 现在还有2个商品
消费了第9个商品 现在还有0个商品貌似出现了线程安全的问题,明明容器里没商品了,消费者依然能消费,而且这个商品也没满足先入后出的规律,纠结了几个小时,脑子已经堵塞了,有没有大侠能帮忙分析下我的代码。。

解决方案 »

  1.   


    //实际上是同步的,只是system.out.println的有点问题
    public class ProducerConsumer { /**
     * @param args
     */ public static void main(String[] args) {
    // TODO Auto-generated method stub
    Container contain = new Container();
    Producer pro = new Producer(contain);
    Consumer con = new Consumer(contain);
    new Thread(con).start();
    new Thread(pro).start(); }}class Item {
    int id; Item(int id) {
    this.id = id;
    } public String toString() {
    return String.valueOf(id);
    }}class Container {
    int index = 0;
    Item[] items = new Item[6]; public synchronized void push(Item item) {
    while (index == items.length) {
    try {
    System.out.println("满了!!!!!!!!!!!!!!!!!!!!!!");
    wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    items[index] = item;
    index++;
    System.out.println("push1个,现在还有" + index+ "个商品");
    notifyAll(); } public synchronized Item pop() { while (index == 0) { try {
    System.out.println("空了!!!!!!!!!!!!!!!!!!!!!!!!!!"); wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    index--;
    notifyAll();
    System.out.println("pop1个,现在还有" + index+ "个商品");
    return items[index]; }}class Producer implements Runnable {
    Container contain = null; Producer(Container contain) {
    this.contain = contain;
    } public void run() { for (int i = 0; i <= 10; i++) {
    Item it = new Item(i);
    contain.push(it);
    // System.out.println("生产了第" + it + "个商品   ");
    //System.out.println("生产了第" + it + "个商品   " + "现在还有" + contain.index+ "个商品");
    } }}class Consumer implements Runnable {
    Container contain = null; Consumer(Container contain) {
    this.contain = contain;
    } public void run() { for (int i = 0; i <= 10; i++) {
    Item it = contain.pop();
    // System.out.println("消费了第" + it + "个商品   ");
    //System.out.println("消费了第" + it + "个商品   " + "现在还有" + contain.index+ "个商品");
    } }
    }
      

  2.   

    生产和消费的方法都是synchronized 的,所以生产的时候,不会消费;消费的时候也不会生产。
    另外,不是满了才去消费,而是如果空了不能消费,需要等待,就是 wait()的作用,进入阻塞状态,让出同步锁,给生产线程,生产出来后,通过notify()方法,通知消费线程,让出同步锁。消费线程从阻塞进入就绪状态,拿到同步锁,进行消费。
    对于生产线程一样,数组满了的话,就不能再生产了。等待消费了以后,有空间才再生产。