下面这个为什么会死锁?执行的方法不同啊?谢谢package deadlock;class A{
public synchronized void say(B b ){
System.out.println("In A class, say method, thread = "+Thread.currentThread().getName());
System.out.println("A类中进");
 b.last();
}
synchronized void last(){
System.out.println("In A class, last method, thread = "+Thread.currentThread().getName());
System.out.println("b 结束");
}
}
class B{
public synchronized void say(A a){
System.out.println("In B class, say method, thread = "+Thread.currentThread().getName());
System.out.println("B类中进 ");
a.last();
}
synchronized void last(){
System.out.println("In B class, last method, thread = "+Thread.currentThread().getName());
System.out.println("a 结束");
}
}
public class DeadlockDemo implements Runnable {

A a = new A();
B b = new B();

public DeadlockDemo(){
System.out.println("In constructor thread = "+Thread.currentThread().getName());
new Thread(this).start();
b.say(a);
}

/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("In main current thread = "+Thread.currentThread().getName());
new DeadlockDemo();
} @Override
public void run() {
// TODO Auto-generated method stub
a.say(b);
}}

解决方案 »

  1.   

    总的来看有两条线程:主线程main,在DeadlockDemo的构造函数中启动了子线程,假设名为run好了。注意到A类和B类,所有函数都带有synchronized,这是对整个实例(对象)有效的;main执行了:b.say(a);
    1、JVM调用b.say函数的同时锁定b实例;
    2、say函数中调用a.last();
    3、JVM调用调用a.last函数的同时锁定a实例;
    4、执行结束。run执行了:a.say(b);
    1、JVM调用a.say函数的同时锁定a实例;
    2、say函数中调用b.last();
    3、JVM调用调用b.last函数的同时锁定b实例;
    4、执行结束。那么由于是并发执行,如果目前的状态是:main执行了它第(1)步的同时,run也刚好执行了它的第(1)步,那么接下来似乎谁都没机会去锁定对方了。也就是main持有了b的锁,并请求a的锁;而run持有了a的锁,并请求b的锁。这就是死锁,so ga
      

  2.   

    想消除死锁,可以把AB各自last函数上的synchronized关键字去掉。
      

  3.   

    A a = new A();
        B b = new B();
    这是你new的两个对象,而你启动线程调用的方法分别为a.say(b);和b.say(a);
    而根据你的上面的方法可以看出每个方法都是有锁的。
    当a.say里面还没有执行b.last();的时候线程休息了,现在b.say开始执行,
    这个时候a和b对象都是分别获得了锁的,现在a.say方法里面的b.last是永远都无法执行的,因为他获取不到锁了,同样,b.say方法里面的a.last也不会去执行了,他们都需要对方的对象,而对方都把自己的对象锁定了的,这样就造成了死锁
      

  4.   

    1 谢谢楼上楼上回复;楼上哥们都提到锁对象了,但是synchronized 是加在方法上的啊,怎么会锁对象了呢?
    2 如果类A和类B中随便加一个无关的非synchronized 方法,死锁就不存在了,何解?
      

  5.   

    关于问题1:
    方法上的synchronized是锁整个对象的,不信另外做个实验就知道了:
    1、取消所有test方法的synchronize,那么你的程序就不会死锁了;做完这步可以先测试下;
    2、给A增加下面这个方法:
        synchronized void nothing() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }
        }
    3、在构造函数的第一句话写:a.nothing();
    关于问题2:
    能结束只是运气好而已吧,只有当main或run有某个提前执行到了3,程序才能顺利结束。
    反正我本机运行过是基本每次都死锁的,即便随意增加几十个非synchronized方法。
      

  6.   

    ..........扯淡吧,4个线程。
    在执行到最后的时候,如: A 在等待 ,B也在等待, C得到锁后 Notify A B 其他线程,C wait 失去锁。
     A B (无先后顺序)得到锁,执行结束。 其中没有线程唤醒C。故C线程无法结束。