俺怀疑不会死锁,所以将程序调了调,并运行了程序: class A{ public A(){} public synchronized void foo(B b){ b.last(); }
public synchronized void last(){ System.out.println("a.last is run."); try{ Thread.sleep(200); }catch(Exception ex){} } }
class B{ public B(){} public synchronized void bar(A a){ a.last(); } public synchronized void last(){ System.out.println("b.last is run."); try{ Thread.sleep(300); }catch(Exception ex){} } }
public class Demo implements Runnable{ A a = new A(); B b = new B(); public Demo(){ (new Thread(this,"Demo")).start(); b.bar(a); } public void run(){ a.foo(b); } public static void main(String args[]){ new Demo(); } }java Demo的结果是: a.last is run. b.last is run. 所以我得出结论不死锁,因为程序用了synchronized,够级别的。
这是典型的可能产生死锁问题的例子.
即相互用户对方需要的锁.
你可以想象一下:
1 匿名线程执行到a.foo(),刚进入这个方法就被中断了 ->
此时此线程拥有a的锁
2 Demo执行到b.bar(),此方法重要执行a.last(),但是不可能,因为执行a.last()就要获得a的锁,\
但a的锁在匿名线程中, 所以Demo等待. 注意此时b的锁被Demo获得了
3 再接1,要执行b.last(), 不可能,因为不可能获得b的锁
4 至此,出现循环等待了, 匿名线程拥有a锁,等待b锁, Demo拥有b锁,等待a锁. 就死锁了so clear吧?
:)
class A{
public A(){}
public synchronized void foo(B b){
b.last();
}
public synchronized void last(){
System.out.println("a.last is run.");
try{
Thread.sleep(200);
}catch(Exception ex){}
}
}
class B{
public B(){}
public synchronized void bar(A a){
a.last();
}
public synchronized void last(){
System.out.println("b.last is run.");
try{
Thread.sleep(300);
}catch(Exception ex){}
}
}
public class Demo implements Runnable{ A a = new A();
B b = new B();
public Demo(){
(new Thread(this,"Demo")).start();
b.bar(a);
}
public void run(){
a.foo(b);
}
public static void main(String args[]){
new Demo();
}
}java Demo的结果是:
a.last is run.
b.last is run.
所以我得出结论不死锁,因为程序用了synchronized,够级别的。
怎么解释呢? 自己领会吧.
不过你要知道的是,这是典型的会产生互相等待的问题.
你说你的程序运行过了,那又怎么样呢?
引申的说 这就是 白盒与黑盒的 区别.
另外,A和B的last()方法中执行的是不相干的动作,他们的运行不需要对方的锁,它们并没有要操作同一个文件或同一条记录,彼此并不干预对方对内部状态。
orange2002(orange)兄说:满足了死锁的条件也未必一定死的....
这一点没有理解透,何以死而未死呢?
这一点没有理解透,何以死而未死呢?”因为他说的条件是指必要条件
调用a.foo()时,锁住对象实例a,当调用b.last()时锁住对象b,但是b.last()无内容,马上返回,释放b的锁,所以不会死锁,如果调的时b.foo()应改就会死锁吧.
请高人指点.
不过看了 biti_9512207(波波斯基) 的回复才发现自己错了
如果执行顺序就像程序写的顺序
1、 new Thread(this,"Demo").start(); // == a.foo()
2、 b.bar();
当然是不会产生死锁,
但是线程的执行顺序不是确定的,
当执行到a.foo()时,如果刚进入方法体,还没有调用b.last()
当前的cpu时间片就用完了,而另一个线程main获得了下一个时间片
这时就出现了 biti_9512207(波波斯基) 所说的那种情况,死锁了
这种情况是完全有可能出现的至于有些朋友说程序里没有争抢资源的情况,解释如下
对方法的同步,是给方法所属的对象加锁,
如程序中,调用a.foo(),就给对象a加锁了,
在a.foo()执行完成之前调用a.last(),last()方法就不能执行,只能等待so,在写多线程的程序时,一定要时刻想到:
一个线程的执行不是连续的,它随时可能被中断
这句话说给大家,也给自己听
new Thread(this,"Demo").start();
b.bar();
}
public void run(){
a.foo();
}
真搞不懂上面的各位都在下咋唬什么?这个程序能通过编译吗?
问:b.bar(), a.foo()那里定义了?
拜托您了,大哥
看清楚了再来说话好不好?