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

生产者消费者有关问题

2011-12-18 
生产者消费者问题下面是我模拟生产者消费者问题的程序,可是怎么会发生死锁呢?wait不是会释放锁码?代码有点

生产者消费者问题
下面是我模拟生产者消费者问题的程序,可是怎么会发生死锁呢?wait不是会释放锁码?代码有点长,分给多一点

Java code
public class ProducerConsumer{    public static void main(String[] args)    {        Basket basket = new Basket(6);                Producer p1 = new Producer(basket);        Producer p2 = new Producer(basket);        Consumer c1 = new Consumer(basket);        Consumer c2 = new Consumer(basket);                Thread t1 = new Thread(p1, "生产者1");        Thread t2 = new Thread(p2, "生产者2");        Thread t3 = new Thread(c1, "消费者1");        Thread t4 = new Thread(c2, "消费者2");                t1.start();        t2.start();        t3.start();        t4.start();    }}class Bread{    int id ;    public Bread(int id)    {        this.id = id;    }}class Basket{    int size;//当前面包数目    int id;//当前面包id    Bread[] breads;//存放面包的数组        public Basket(int n)    {        breads = new Bread[n];    }}class Producer implements Runnable{    Basket basket;//装面包的篮子    boolean isGoOn = true;//是否继续生产        /**     * 构造方法,传递篮子     */    public Producer(Basket basket)    {        this.basket = basket;    }        /**     * 重写run方法,当篮子不满的时候继续生产,     * 满的时候wait     */    @Override    public synchronized void run()    {        while (isGoOn)        {            try            {                Thread.sleep((int)(Math.random()*1000));                                if (basket.size < basket.breads.length)//篮子不满                {                    /*往当前篮子装面包,装完id和size分别加1*/                    System.out.print(Thread.currentThread().getName()                            + ": 生产的是" + basket.id  + "号面包,");                    basket.breads[basket.size++] = new Bread(basket.id++);                    System.out.println("现在共有" + basket.size + "个面包");                                        /*篮子装的是第一个包子时,唤醒消费者*/                    if (basket.size == 1)                    {                        System.out.println(Thread.currentThread().getName()                                +" :有包子了,可以来吃了!");                        this.notifyAll();                    }                }                /*篮子满了,等待*/                if (basket.size == basket.breads.length)                {                    System.out.println(Thread.currentThread().getName()                                +" :篮子满了,请快点吃!");                    wait();                }            }catch (InterruptedException e)            {                e.printStackTrace();            }        }        }}class Consumer implements Runnable{    Basket basket;//装面包的篮子    boolean isGoOn = true;//是否继续消费        /**     * 构造方法,传递篮子     */    public Consumer(Basket basket)    {        this.basket = basket;    }        /**     * 重写run方法,当篮子有面包时的时候可以消费,     * 没有的时候wait     */    @Override    public synchronized void run()    {        while (isGoOn)        {            try            {                Thread.sleep((int)(Math.random()*1000));                                if (basket.size > 0)//篮子不为空                {                    /*往当前篮子拿面包,拿的是id-1号面包,拿完size减1*/                    System.out.print(Thread.currentThread().getName()                            + ":拿的是" + --basket.id + "号面包,");                    basket.size--;                    System.out.println("现在还剩" + basket.size + "个面包");                                        /*篮子拿的是最上面一个包子时,唤醒生产者*/                    if (basket.size == basket.breads.length - 1)                    {                        System.out.println(Thread.currentThread().getName()                                + ": 篮子有空位,可以继续生产了!");                        this.notifyAll();                    }                }                /*篮子为空,等待*/                if (basket.size == 0)                {                    System.out.println(Thread.currentThread().getName()                                + " :篮子空了,请快点生产!");                    wait();                    }                }catch (InterruptedException e)            {                e.printStackTrace();            }        }        }} 



[解决办法]
LZ没有弄清楚 锁 的概念
Producer p1 = new Producer(basket);
Producer p2 = new Producer(basket);
Consumer c1 = new Consumer(basket);
Consumer c2 = new Consumer(basket);
//p1和p2是两个不同的对象,所以你在p1和p2的run上syncronized没有意义
//同理c1和c2一样
注意到这些对象都是用同一个basket,所以你的synchronized应该做在basket才有意义

Thread t1 = new Thread(p1, "生产者1");
Thread t2 = new Thread(p2, "生产者2");
Thread t3 = new Thread(c1, "消费者1");
Thread t4 = new Thread(c2, "消费者2");
//这里和上面一样t1和t2是用的不同的p1和p2,所以相互之间没有影响


Java code
class Producer implements Runnable{    Basket basket;//装面包的篮子    boolean isGoOn = true;//是否继续生产        /**     * 构造方法,传递篮子     */    public Producer(Basket basket)    {        this.basket = basket;    }        /**     * 重写run方法,当篮子不满的时候继续生产,     * 满的时候wait     */    @Override    public void run()    {        while (isGoOn)        {            try            {                Thread.sleep((int)(Math.random()*1000));synchronized(basket) {                                if (basket.size < basket.breads.length)//篮子不满                {                    /*往当前篮子装面包,装完id和size分别加1*/                    System.out.print(Thread.currentThread().getName()                            + ": 生产的是" + basket.id  + "号面包,");                    basket.breads[basket.size++] = new Bread(basket.id++);                    System.out.println("现在共有" + basket.size + "个面包");                                        /*篮子装的是第一个包子时,唤醒消费者*/                    if (basket.size > 0) //                    {                        System.out.println(Thread.currentThread().getName()                                +" :有包子了,可以来吃了!");                        basket.notifyAll();                    }                }                /*篮子满了,等待*/                if (basket.size == basket.breads.length)                {                    System.out.println(Thread.currentThread().getName()                                +" :篮子满了,请快点吃!");                    basket.wait();                }} //synchronized end            }catch (InterruptedException e)            {                e.printStackTrace();            }        }        }}class Consumer implements Runnable{    Basket basket;//装面包的篮子    boolean isGoOn = true;//是否继续消费        /**     * 构造方法,传递篮子     */    public Consumer(Basket basket)    {        this.basket = basket;    }        /**     * 重写run方法,当篮子有面包时的时候可以消费,     * 没有的时候wait     */    @Override    public void run()    {        while (isGoOn)        {            try            {                Thread.sleep((int)(Math.random()*1000));synchronized(basket) {                                if (basket.size > 0)//篮子不为空                {                    /*往当前篮子拿面包,拿的是id-1号面包,拿完size减1*/                    System.out.print(Thread.currentThread().getName()                            + ":拿的是" + --basket.id + "号面包,");                    basket.size--;                    System.out.println("现在还剩" + basket.size + "个面包");                                        /*篮子拿的是最上面一个包子时,唤醒生产者*/                    if (basket.size < basket.breads.length)                    {                        System.out.println(Thread.currentThread().getName()                                + ": 篮子有空位,可以继续生产了!");                        basket.notifyAll();                    }                }                /*篮子为空,等待*/                if (basket.size == 0)                {                    System.out.println(Thread.currentThread().getName()                                + " :篮子空了,请快点生产!");                    basket.wait();                    }    } //synchronized end            }catch (InterruptedException e)            {                e.printStackTrace();            }        }        }} 


[解决办法]
wait不是会释放锁码? wait是线程等待,需要唤醒的。
[解决办法]
+1

探讨
wait不是会释放锁码? wait是线程等待,需要唤醒的。

[解决办法]
有意思

热点排行