本帖最后由 aazbc 于 2012-12-24 23:00:53 编辑

解决方案 »

  1.   

    你应该把单一的get和set写成线程安全的(换句话,就是保证生产和消费一个产品的过程为原子性的);而你的程序的原子性太大了,保证了一次性生产或者消费掉所有的产品。还有多线程中的条件判断因该写成while形式的,把:if (flag != 0) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }改为while(flag != 0) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
      

  2.   

    不好意思,要求看错。
    一次 生产 5个面包,一次 消费 5个面包。得修改循环条件。for (int i = counts; i >= 1; --i) {这个条件并不是保证一次生产5个面包。一次性要取出5个面包的话,要保证面包数>=5才可以执行,所以等待条件应该是,flag<5,下面的代码有问题
    if (flag == 0) {...} 
    同样set方法也有问题,应该保证能够容纳5个面包。
      

  3.   


    public class ProducerConsumer {

    public static void main(String[] args)
    {
    Bag b = new Bag();
    Producer p = new Producer(b);
    Consumer c = new Consumer(b);
    new Thread(p).start();
    new Thread(c).start();
    }
    }
    class Bread
    {
    private int id;

    public Bread(int id)
    {
    this.id = id;
    }

    public String toString()
    {
    return "I am Bread : " + id;
    }
    }class Bag
    {
    Bread[] bread = new Bread[5];
    private int index = 0;
    public synchronized void set(Bread b)
    {
    while(index == bread.length)
    {
    try
    {
    this.wait();

    catch (InterruptedException e) 
    {
    e.printStackTrace();
    }
    }
    this.notify();
    bread[index] = b;
    index ++;
    }

    public synchronized Bread get()
    {
    while(index == 0)
    {
    try
    {
    this.wait();

    catch (InterruptedException e) 
    {
    e.printStackTrace();
    }
    }
    this.notify();
    index --;
    return bread[index];
    }
    }class Producer implements Runnable
    {
    Bag bag;

    public Producer(Bag bag)
    {
    this.bag = bag;
    }

    public void run()
    {
    for(int i=1; i<=20; i++)
    {
    Bread b = new Bread(i);
    bag.set(b);
    System.out.println("Producer : " + b);
    try
    {
    Thread.sleep(1000);
    }
    catch(InterruptedException e)
    {
    e.printStackTrace();
    }
    }
    }
    }class Consumer implements Runnable
    {
    Bag bag;

    public Consumer(Bag bag)
    {
    this.bag = bag;
    }

    public void run()
    {
    for(int i=1; i<=20; i++)
    {
    Bread b = bag.get();
    System.out.println("Consumer : " + b);
    try
    {
    Thread.sleep(1000);
    }
    catch(InterruptedException e)
    {
    e.printStackTrace();
    }
    }
    }
    }
    参考参考。。