谁能帮我解释下以下这段代码是怎么运行的?没有理解,怎么就造成了死锁呢?synchronized关键字到底是锁DemoA还是锁FunA或者锁住的是FunA+Fun2?
按我的理解是应该打印:
DemoA--->进去DemoA中的FunA(DemoB db)方法!!!!!
DemoB--->进去DemoB中的void fun2()方法!!!!!
DemoB--->进去DemoB中的funB(DemoA da)方法!!!!!
DemoA--->进去DemoA中的void fun2()方法!!!!!
实际上打印的内容是:
DemoA--->进去DemoA中的FunA(DemoB db)方法!!!!!
DemoB--->进去DemoB中的funB(DemoA da)方法!!!!!
以下代码出自李兴华多线程第四讲~class DemoA { public synchronized void funA(DemoB db){
System.out.println("DemoA--->进去DemoA中的FunA(DemoB db)方法!!!!!");
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
db.fun2();
}

public synchronized void fun2(){
System.out.println("DemoA--->进去DemoA中的void fun2()方法!!!!!");
}
}class DemoB {
public synchronized void funB(DemoA da){
System.out.println("DemoB--->进去DemoB中的funB(DemoA da)方法!!!!!");
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
da.fun2();
}
public synchronized void fun2(){
System.out.println("DemoB--->进去DemoB中的void fun2()方法!!!!!");
}
}
class ThreadDead implements Runnable{
private DemoA da=new DemoA();
private DemoB db=new DemoB();
public ThreadDead(){
new Thread(this).start();
da.funA(db);
}
public void run(){
db.funB(da);
}
}
public class ThreadDemo16 {
public static void main(String[] args) {
new ThreadDead();
}
}

解决方案 »

  1.   

    两个线程,一个main,一个start启动的。main中da.funA(db)锁住了da,另一个run中db.funB()锁住了db,
    funA()和funB()又互调,所以就锁了
      

  2.   

    可不可以这样理解,一个class相当于一个房子,里面多个void相当于多个房间,带synchronized关键字的void相当于房间加了锁,不管怎么处理,只有一把钥匙?
      

  3.   


        public ThreadDead(){
            new Thread(this).start();
            da.funA(db);
        }
        public void run(){
            db.funB(da);
        }new Thread(this).start();这一行代码表示构造一个Thread对象并启动线程,但是线程初始化有一定的系统开销(run方法并非立即执行),所以,下面一行代码da.funA(db)将会比run方法中的db.funB(da)先被执行。当前线程在执行da.funA(db)时获得da对象锁;
    新线程(通过new Thread构造的线程)执行run方法中的db.funB(da)时获得db对象锁;
    当前线程执行到db.fun2()时,新线程仍阻塞在Thread.sleep(100)、db对象锁未释放,当前线程因无法获得db对象锁而发生阻塞;
    新线程执行到da.fun2()时,当前线程仍阻塞在db.fun2()、da对象锁未释放,新线程因无法获得da对象锁而发生阻塞;
    此时这两个线程互相控制对方所需访问资源的锁,并且都因为得不到锁而阻塞,即产生死锁。
      

  4.   

    同一个实例的同一个synchonized方法不允许一个以上的线程同时访问,记住是同一个实例,如何确定synchronized锁定的是谁呢,就是哪个对象实例调用的这个synchonized方法,它就锁定哪个实例。
    上述实例:main线程先去start了一个ThreadDead线程,但是start以后不会马上去执行它的run方法,main线程先走到了da.funA(db),da此时被锁住,main线程sleep,ThreadDead线程run方法起来了运行db.funB(da),此时db被锁住,此时main恢复运行执行db.fun2(),发现db的锁没有被释放,在此等待获得db锁,而ThreadDead执行到da.fun2()时发现da锁也没有释放,他又想获取这个da的锁,结果也在此等待,故此时产生死锁。
    解决方案:由于db.fun2()和da.fun2()不涉及的共享数据冲突的问题,把synchonized去掉即可
      

  5.   

    synchronized 加在方法上时应该相当于给实例对象加锁,同一时间只可以有一个方法调用这个对象。
      

  6.   

    锁的含义是锁定调用该方法的对象,注意是这个对象,并且针对的是这个方法,也就是没解锁的时候,这个对象是不能调用此方法的,但是其它的方法还是可以调用的,再但是,当其它的方法也加上synchronized的时候,标明其它方法也加入到锁定之内,这时一旦对象加上的锁(也就是不管哪个加锁的方法调用了),所有加锁的所有方法都被锁了,这个时候就不能访问了
    参考:http://www.lookhan.com/javase/javase/20110103162113.html