当前位置: 代码迷 >> J2SE >> 死锁有关问题,大神啊
  详细解决方案

死锁有关问题,大神啊

热度:67   发布时间:2016-04-23 20:08:09.0
死锁问题,大神求助啊~~~
我这段代码就是模拟最基本的生产者和消费者的例子,为了观察线程故意做了两层嵌套的同步代码块,几乎每次都会死锁,代码如下,

//共享资源类
class Resource
{
//商品名
private String name;
//商品数量
private int count = 1;
//标记
private boolean flag = false;

//两个锁对象
private Object obj_pro = new Object();
private Object obj_con = new Object();

//生产方法,为方便观察几乎为每一步都添加了输出语句
public void produce(String name)
{
System.out.println(Thread.currentThread().getName()+"------------pro1");
//第一层同步代码块,使用obj_con锁
synchronized(obj_con)
{
System.out.println(Thread.currentThread().getName()+"------------pro2");
//第二层同步代码块,使用obj_pro锁
synchronized(obj_pro)
{
System.out.println(Thread.currentThread().getName()+"------------pro3");
//当标记为真时,表明生产了一个商品,等待
while(flag)
{
System.out.println(Thread.currentThread().getName()+"------------pro4");
//通过condition_pro对象只冻结生产者线程
try{obj_pro.wait();}catch(InterruptedException  e){}
}

this.name = name+"--"+count++;

System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
flag = true;

//只唤醒消费者线程
obj_con.notify();
System.out.println(Thread.currentThread().getName()+"------------pro5");
}
System.out.println(Thread.currentThread().getName()+"------------pro6");
}
System.out.println(Thread.currentThread().getName()+"------------pro7");
}
//消费方法
public void consume()
{
System.out.println(Thread.currentThread().getName()+"------------con1");
synchronized(obj_con)
{
System.out.println(Thread.currentThread().getName()+"------------con2");
synchronized(obj_pro)
{
System.out.println(Thread.currentThread().getName()+"------------con3");
while(!flag)
{
System.out.println(Thread.currentThread().getName()+"------------con4");
//冻结消费者线程
try{obj_con.wait();}catch(InterruptedException e){}
}

System.out.println(Thread.currentThread().getName()+"..........消费者.........."+this.name);
flag = false;

//唤醒生产者线程
obj_pro.notify();

System.out.println(Thread.currentThread().getName()+"------------con5");
}
System.out.println(Thread.currentThread().getName()+"------------con6");
}
System.out.println(Thread.currentThread().getName()+"------------con7");
}
}
//生产者
class Producer implements Runnable
{
private Resource res;
Producer(Resource res)
{
this.res = res;
}

public void run()
{
while(true)
{
res.produce("+商品+");
}
}
}
//消费者
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}

public void run()
{
while(true)
{
res.consume();
}
}
}
class ProducerConsumerDemo
{
public static void main(String[] args) 
{
//创建资源类
Resource res = new Resource();

//创建生产者和消费者对象
Producer pro = new Producer(res);
Consumer con = new Consumer(res);

Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}


运行结果通常是这样的:
Thread-1------------pro1
Thread-2------------con1
Thread-3------------con1
Thread-0------------pro1
Thread-1------------pro2
Thread-1------------pro3
Thread-1...生产者...+商品+--1
Thread-1------------pro5
Thread-1------------pro6
Thread-1------------pro7
Thread-0------------pro2
Thread-1------------pro1
Thread-0------------pro3
Thread-0------------pro4

我的问题是,就像上面的结果那样,如果按照wait方法的特性,0号线程等待以后,将会释放其所持有的锁对象,但是为什么其他线程均止步于“pro1”或者“con1”,这表明其他三个线程压根就没有拿到锁,都没有开始执行同步代码块,难道说wait方法不会释放持有的全部锁对象吗?而是指释放最近获取的锁?希望高手指点啊~~~
------解决思路----------------------

try{obj_pro.wait();}catch(InterruptedException  e){}//这句只会释放obj_pro,不会释放obj_con,所以你的消费者基本没有机会获取到obj_con
  相关解决方案