//----------------------------------------------------   
// 商品   
class Goods {      
    private int id;   
    public Goods(int id) { this.id = id; }   
       
    public String toString() {   
        return "Goods: " + id;   
    }   
}   
//----------------------------------------------------   
// 装东西的容器   
class Stack {      
    private int index = 0;   
    private Goods[] buffer = new Goods[5];  // 生产者和消费者共享的有界缓冲区   
       
    public synchronized void push(Goods goods) {   
        while(index == buffer.length) {   
            try {   
                this.wait();       
            } catch (InterruptedException e) { e.printStackTrace(); }   
        }   
        this.notify();   
        buffer[index] = goods;   
        index++;   
    }   
       
    public synchronized Goods pop() {   
        while(index == 0) {   
            try {   
                this.wait();   
            } catch (InterruptedException e) { e.printStackTrace(); }   
        }   
        this.notify();   
        index--;   
        return buffer[index];   
    }   
}   
//----------------------------------------------------   
// 生产者线程   
class Producer implements Runnable {       
    private Stack s = null;   
    public Producer(Stack s) { this.s = s; }   
    public void run() {   
        for(int i = 0; i <= 10; i++) {   
            Goods g = new Goods(i);   
            s.push(g);   
            System.out.println("生产了 " + g);   
            try {   
                Thread.sleep(1000);   
            } catch (InterruptedException e) { e.printStackTrace(); }   
        }   
    }   
}   
//----------------------------------------------------   
// 消费者线程   
class Consumer implements Runnable {       
    private Stack s = null;   
    public Consumer(Stack s) { this.s = s; }   
    public void run() {   
        for(int i = 0; i <= 10; i++) {   
            Goods g = s.pop();   
            System.out.println("消费了 " + g);   
            try {   
                Thread.sleep(1000);   
            } catch (InterruptedException e) { e.printStackTrace(); }   
        }   
    }   
}   
//----------------------------------------------------   
// 主方法   
public class test {   
    public static void main(String[] args) {   
        Stack s = new Stack();   
        Producer p = new Producer(s);   
        Consumer c = new Consumer(s);   
        new Thread(p).start();   
        new Thread(c).start();   
    }   
          }
打印结果是:
生产了 Goods: 0
消费了 Goods: 0
消费了 Goods: 1
生产了 Goods: 1
生产了 Goods: 2
消费了 Goods: 2
生产了 Goods: 3
消费了 Goods: 3
生产了 Goods: 4
消费了 Goods: 4
生产了 Goods: 5
消费了 Goods: 5
生产了 Goods: 6
消费了 Goods: 6
生产了 Goods: 7
消费了 Goods: 7
生产了 Goods: 8
消费了 Goods: 8
消费了 Goods: 9
生产了 Goods: 9
生产了 Goods: 10
消费了 Goods: 10
其中第三行不是出现错误了吗?没生产就消费了1号good,这个是怎么回事呢,是不是代码写错了?

解决方案 »

  1.   

    多线程问题,你只锁了容器而已,这样保证了容器的安全,但你是多线程,生产者生产了一个东西,然后丢到容器里去,完了离开同步方法后再叫唤说我生产了,真实的生产和生产完了之后的打印存在空隙,可能被消费者钻空子。你按照如下的改,将生产和消费字样的打印写到push和pop这两个同步方法里去。
      

  2.   

    这个不奇怪
    线程的执行时间是由CPU随机分配的,你的线程的打印(print)处理是放在sychronized方法(push和pop)外的,所以打印(print)和synchronized可能就不一致了,你如果把print写在push和pop里,那就肯定是一致了