下面是我模拟生产者消费者问题的程序,可是怎么会发生死锁呢?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();
}
}
}
}
{
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();
}
}
}
}
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();
}
}
}
}