下面是我模拟生产者消费者问题的程序,可是怎么会发生死锁呢?wait不是会释放锁码?代码有点长,分给多一点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();
}
}
}
}

解决方案 »

  1.   

    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,所以相互之间没有影响
    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();
                }
            }    
        }
    }
      

  2.   

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