首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java相关 >

多个生产者多个消费者有关问题,帮忙看看吧,感激不尽

2012-06-01 
多个生产者多个消费者问题,帮忙看看吧,感激不尽桌子上有一个盘子,每次只能放一个水果,爸爸只放苹果,儿子专

多个生产者多个消费者问题,帮忙看看吧,感激不尽
桌子上有一个盘子,每次只能放一个水果,爸爸只放苹果,儿子专门等着吃苹果;妈妈只放橘子,女儿专门等着吃橘子,只有盘子为空时,爸爸或妈妈才可以放水果,盘里有水果是,儿子或者女儿才能从盘子里取出
下面是我程序

Java code
/** * 水果类 * 唯一标示 * @author Arthur * */public class Fruits {   private String name;         public Fruits(String name){       this.name = name;   }   @Override   public String toString(){       return name;   }}/** * 橘子类 * @author Arthur * */public class Orange extends Fruits {    public Orange(String name) {        super(name);            }}/** * 苹果类 * @author Arthur * */public class Apple extends Fruits {    public Apple(String name) {        super(name);    }}

下面是苹果生产者和苹果消费者类
Java code
/** * 生产苹果的生产者 *  * @author Arthur *  */public class ProducerApple implements Runnable {    CriticalResources cr = null;// 封装一个临界资源对象,以便生产    public ProducerApple(CriticalResources cr) {        super();        this.cr = cr;    }    @Override    public void run() {        synchronized (this) {            if (cr.getFruites()[0] instanceof Orange||cr.getFruites()[0]!=null) {                try {                    this.wait();//缓冲区满,该生产者等待                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }                    synchronized (this) {                Fruits fruits = new Apple("苹果");                cr.push(fruits);                System.out.println("苹果生产商生产了" + fruits);                // try {                // Thread.sleep(1000);                // } catch (InterruptedException e) {                // // TODO Auto-generated catch block                // e.printStackTrace();                // }//            }        }        synchronized (cr.getCa()) {            cr.getCa().notify();        }    }}/** * 消费苹果的消费者 *  * @author Arthur *  */public class ConsumerApple implements Runnable {    private CriticalResources cr = null;// 封装一个临界资源对象,以便消费    public ConsumerApple(CriticalResources cr) {        super();        this.cr = cr;    }    @Override    public void run() {        while (cr.getFruites()[0] != null                && cr.getFruites()[0] instanceof Orange) {            synchronized (this) {                try {                    this.wait();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }                synchronized (cr.getPa()) {            Fruits fruits = cr.pop();            System.out.println("----苹果消费者消费了-------" + fruits);            cr.getPa().notify();        }        // try {        // Thread.sleep(2000);        // } catch (InterruptedException e) {        // // TODO Auto-generated catch block        // e.printStackTrace();        // }    }}/** * 生产橘子的生产者 *  * @author Administrator *  */public class ProducerOrange implements Runnable {    CriticalResources cr = null;    public ProducerOrange(CriticalResources cr) {        super();        this.cr = cr;    }    @Override    public void run() {        synchronized(this){            if(cr.getFruites()[0] instanceof Apple||cr.getFruites()[0]!=null){                try {                    this.wait();//该生产这等待                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }           }                    }        while (cr.getFruites()[0] ==null) {                        synchronized (this) {                Fruits fruits = new Orange("橘子");                cr.push(fruits);                System.out.println("橘子生产商生产了" + fruits);            }            //                    }                synchronized(cr.getCo()){            cr.getCo().notify();//橘子消费者唤醒该橘子生产者        }    }}/** * 消费橘子的消费者 *  * @author Administrator *  */public class ConsumerOrange implements Runnable {    private CriticalResources cr = null;// 封装一个临界资源对象,以便消费    public ConsumerOrange(CriticalResources cr) {        super();        this.cr = cr;    }    @Override    public void run() {        //如果缓冲区是苹果        while (cr.getFruites()[0]!= null                && cr.getFruites()[0] instanceof Apple) {            synchronized (this) {                try {                    this.wait();//该消费者等待                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }                        }                        synchronized (cr.getPo()) {            Fruits fruits = cr.pop();            System.out.println("----橘子消费者消费了-------" + fruits);            cr.getPo().notify();        }            }} 


客户端
Java code
public class Client {    /**     * @param args     */    public static void main(String[] args) {        CriticalResources cr = new CriticalResources();        //生产苹果实例        ProducerApple appleP = new ProducerApple(cr);        //消费苹果实例        ConsumerApple appleC = new ConsumerApple(cr);                //橘子生产者实例        ProducerOrange orangeP = new ProducerOrange(cr);        //橘子消费者实例        ConsumerOrange orangeC = new ConsumerOrange(cr);        //生产苹果线程        Thread pThread = new Thread(appleP);        //消费苹果线程        Thread cThread = new Thread(appleC);        //生产橘子线程        Thread pt = new Thread(orangeP);        //消费橘子线程        Thread ct = new Thread(orangeC);                        pt.start();                pThread.start();        cThread.start();                ct.start();    }}

临界资源
Java code
/** * 临界资源 * @author Arthur * */public class CriticalResources {    private int index = 0;    private Fruits[] fruites = new Fruits[1];//默认临界区有五个商品    private ProducerApple pa = new ProducerApple(this);    private ProducerOrange po = new ProducerOrange(this);    private ConsumerApple ca = new ConsumerApple(this);    private ConsumerOrange co = new ConsumerOrange(this);    /**     * 向临界资源里添加商品     * 利用synchronized关键字实现同步     * 添加后数组指针+1     * 如果临界资源数组里面装满了商品不能再生产,则生产线程等待以便让消费者消费     * @param goods     */    public synchronized void push(Fruits goods){        //        if(this.index == this.fruites.length){            try {                this.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }                this.notify();//唤醒生产者        this.fruites[index++] = goods;    }        /**     * 从临界资源里拿商品,先减一后返回     * 如果index==0说明,临界资源数组里面没有商品,不能在消费     * 消费线程阻塞,让生产者生产     * 则让生产者     * @return     */    public synchronized Fruits pop(){        if(this.index == 0){            try {                this.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }                this.notify();//唤醒消费者        return fruites[--index];    }    public int getIndex() {        return index;    }    public void setIndex(int index) {        this.index = index;    }    public ProducerApple getPa() {        return pa;    }    public void setPa(ProducerApple pa) {        this.pa = pa;    }    public ProducerOrange getPo() {        return po;    }    public void setPo(ProducerOrange po) {        this.po = po;    }    public ConsumerApple getCa() {        return ca;    }    public void setCa(ConsumerApple ca) {        this.ca = ca;    }    public ConsumerOrange getCo() {        return co;    }    public void setCo(ConsumerOrange co) {        this.co = co;    }    public Fruits[] getFruites() {        return fruites;    }    public void setFruites(Fruits[] fruites) {        this.fruites = fruites;    }    }

但是运行结果是

橘子生产商生产了橘子
----橘子消费者消费了-------橘子
然后一直保持运行状态,没有在输出生产和消费苹果信息?怎么回事儿

[解决办法]
怎么这么多 同步代码块 
wait()的时候应该判断一下
[解决办法]
有些类的代码没有修改,就不再贴出来了。
请楼主自己比较哪些地方改了。
有疑问鄙人乐意解释。
Java code
// 下面是苹果生产者和苹果消费者类class ProducerApple implements Runnable {    CriticalResources cr = null;// 封装一个临界资源对象,以便生产    public ProducerApple(CriticalResources cr) {        super();        this.cr = cr;    }    int count = 5; //做5次    @Override    public void run() {        while(count-->0)        synchronized (cr) {            while ((cr.peek() != null) ) {                try {                    cr.wait();// 缓冲区满,该生产者等待                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            Fruits fruits = new Apple("苹果");            cr.push(fruits);            System.out.println("苹果生产商生产了" + fruits);            cr.notifyAll();        }    }}/** * 消费苹果的消费者 *  * @author Arthur *  */class ConsumerApple implements Runnable {    private CriticalResources cr = null;// 封装一个临界资源对象,以便消费    public ConsumerApple(CriticalResources cr) {        super();        this.cr = cr;    }    int count = 5; //做5次    @Override    public void run() {        while(count-->0)            synchronized (cr) {                while (!(cr.peek() instanceof Apple) ) {                    try {                        cr.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                Fruits fruits = cr.pop();                System.out.println("----苹果消费者消费了-------" + fruits);                cr.notifyAll();                            }    }}/** * 生产橘子的生产者 *  * @author Administrator *  */class ProducerOrange implements Runnable {    CriticalResources cr = null;    public ProducerOrange(CriticalResources cr) {        super();        this.cr = cr;    }    int count = 5; //做5次    @Override    public void run() {        while(count-->0)        synchronized (cr) {            while (cr.peek() != null) {                try {                    cr.wait();// 该生产这等待                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }            Fruits fruits = new Orange("橘子");            cr.push(fruits);            System.out.println("橘子生产商生产了" + fruits);            cr.notifyAll();        }    }}/** * 消费橘子的消费者 *  * @author Administrator *  */class ConsumerOrange implements Runnable {    private CriticalResources cr = null;// 封装一个临界资源对象,以便消费    public ConsumerOrange(CriticalResources cr) {        super();        this.cr = cr;    }    int count = 5; //做5次    @Override    public void run() {        while(count-->0)        // 如果缓冲区是苹果        synchronized (cr) {        while (!(cr.peek() instanceof Orange)) {            try {                    cr.wait();// 该消费者等待                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        Fruits fruits = cr.pop();        System.out.println("----橘子消费者消费了-------" + fruits);        cr.notifyAll();        }    }}// 客户端public class Client {    /**     * @param args     */    public static void main(String[] args) {//        System.out.println(null instanceof Orange);        CriticalResources cr = new CriticalResources();        // 生产苹果实例        ProducerApple appleP = new ProducerApple(cr);        // 消费苹果实例        ConsumerApple appleC = new ConsumerApple(cr);        // 橘子生产者实例        ProducerOrange orangeP = new ProducerOrange(cr);        // 橘子消费者实例        ConsumerOrange orangeC = new ConsumerOrange(cr);        // 生产苹果线程        Thread pThread = new Thread(appleP);        // 消费苹果线程        Thread cThread = new Thread(appleC);        // 生产橘子线程        Thread pt = new Thread(orangeP);        // 消费橘子线程        Thread ct = new Thread(orangeC);        pt.start();        pThread.start();        cThread.start();        ct.start();    }}// 临界资源/** * 临界资源 *  * @author Arthur *  */class CriticalResources {    private int index = 0;    private Fruits[] fruites = new Fruits[1];// 默认临界区有0-1个商品    private ProducerApple pa = new ProducerApple(this);    private ProducerOrange po = new ProducerOrange(this);    private ConsumerApple ca = new ConsumerApple(this);    private ConsumerOrange co = new ConsumerOrange(this);    /**     * 向临界资源里添加商品 利用synchronized关键字实现同步 添加后数组指针+1     * 如果临界资源数组里面装满了商品不能再生产,则生产线程等待以便让消费者消费     *      * @param goods     */    public synchronized void push(Fruits goods) {        //        while (this.index == this.fruites.length) {            try {                this.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        this.notifyAll();// 唤醒生产者        this.fruites[index++] = goods;    }    /**     * 从临界资源里拿商品,先减一后返回 如果index==0说明,临界资源数组里面没有商品,不能在消费 消费线程阻塞,让生产者生产 则让生产者     *      * @return     */    public synchronized Fruits pop() {        while (this.index == 0) {            try {                this.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        this.notifyAll();// 唤醒消费者        return fruites[--index];    }    public synchronized Fruits peek() {        if (this.index == 0)             return null;        else            return fruites[index-1];    }    public int getIndex() {        return index;    }    public void setIndex(int index) {        this.index = index;    }    public ProducerApple getPa() {        return pa;    }    public void setPa(ProducerApple pa) {        this.pa = pa;    }    public ProducerOrange getPo() {        return po;    }    public void setPo(ProducerOrange po) {        this.po = po;    }    public ConsumerApple getCa() {        return ca;    }    public void setCa(ConsumerApple ca) {        this.ca = ca;    }    public ConsumerOrange getCo() {        return co;    }    public void setCo(ConsumerOrange co) {        this.co = co;    }    public Fruits[] getFruites() {        return fruites;    }    public void setFruites(Fruits[] fruites) {        this.fruites = fruites;    }} 


[解决办法]
对临界资源进行枷锁,因为修改临界资源时,只能有一个对象对它操作。我理解的。

探讨
为什么生产者的run方法里要对cr枷锁呢?这个不是很明白,麻烦讲解一下谢谢

引用:
有些类的代码没有修改,就不再贴出来了。
请楼主自己比较哪些地方改了。
有疑问鄙人乐意解释。

Java code

// 下面是苹果生产者和苹果消费者类

class ProducerApple implements Runnable {
CriticalRe……

热点排行