public class DeadThread extends Thread{
static Integer a = new Integer(0);
static Integer b = new Integer(0);
boolean flag;

public void run() {
if (flag) {
synchronized (a){
a = new Integer(a.intValue()+1);
System.out.println(Thread.currentThread().getName()+"拿到 a  "+a);

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (b){
b = new Integer(b.intValue()+1);
System.out.println(Thread.currentThread().getName()+"拿到b  " +b);
};
};
}else {
synchronized (b) {
b = new Integer(b.intValue()+1);
System.out.println(Thread.currentThread().getName()+"拿到b  "+b);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(a) {
a = new Integer(a.intValue()+1);
System.out.println(Thread.currentThread().getName()+"拿到a  "+a);
}
}

}
}
public DeadThread(boolean flag) {
this.flag = flag;
}


public static void main(String[] args) {
DeadThread d1 = new DeadThread(true);
d1.start();
DeadThread d2 = new DeadThread(false);
d2.start();
}
}
输出:
Thread-0拿到a  1
Thread-1拿到b  1
Thread-1拿到a  2
Thread-0拿到b  2
为什么Thread-0和Thread-1都能拿到a,b 不是应该各自只拿到一个吗?

解决方案 »

  1.   

    是因为当第一个线程运行到synchronized (a)时。那么第二个线程就执行synchronized (b)这时a的值加一b的值加一。那么这个时候哪个线程再互换。所以ab就都加了一再输出来。
      

  2.   

    这中情况下是不会造成死锁的,初始锁的是a、b都未0的内存地址,进去到if或者else,对a、b进行操作,内存地址变了,所以跟之前的a、b地址锁就没关系了,就会有那样的结果打出来     锁永远是锁内存地址的  内存地址变了  
      

  3.   

    晕倒,楼主想这个synchronized(object)来玩死锁,那肯定不行的。
    首先你要明白 synchronized(object) 这个意思,也就是在这个代码块里面,同时只有一个执行。
    你的程序是两个程序了,不是同一块代码块。是两个类里面的代码,锁毛啊。
    object不是锁。他只是钥匙。如果你想用说,就用reenlock的lock显式的调用。
      

  4.   


    public class DeadThread extends Thread{
    static Integer a = new Integer(0);
    static Integer b = new Integer(0);
    boolean flag;

    public void run() {
    if (flag) {
    synchronized (a){
    //a = new Integer(a.intValue()+1);
    System.out.println(Thread.currentThread().getName()+"拿到 a  "+a);

    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    synchronized (b){
    //b = new Integer(b.intValue()+1);
    System.out.println(Thread.currentThread().getName()+"拿到b  " +b);
    };
    };
    System.out.println("true over");
    }else {
    synchronized (b) {
    //b = new Integer(b.intValue()+1);
    System.out.println(Thread.currentThread().getName()+"拿到b  "+b);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    synchronized(a) {
    //a = new Integer(a.intValue()+1);
    System.out.println(Thread.currentThread().getName()+"拿到a  "+a);
    }
    }
    System.out.println("false over");
    }
    }
    public DeadThread(boolean flag) {
    this.flag = flag;
    }


    public static void main(String[] args) {
    DeadThread d1 = new DeadThread(true);
    d1.start();
    DeadThread d2 = new DeadThread(false);
    d2.start();

    }
    }
    输出:
    Thread-0拿到 a  0
    Thread-1拿到b  0应该是死锁了,因为没有输出over。谁能解释一下。
      

  5.   


    DeadThread d1 = new DeadThread(true);
    d1.start();
    DeadThread d2 = new DeadThread(false);
    d2.start();//1.启动d1线程,调用run()方法,判断flag值,flag为true,d1拿到a锁,输出“Thread-0拿到 a 0
    ”,d1线程sleep;
    //2.此时d2线程,启动,调用run(),判断flag值,flag为false,执行else,d2线程拿到b锁,输出“Thread-1拿到b 0”,d2线程sleep;
    //3.当d1线程睡眠时间到,继续执行,进行b锁判断,相要得到b锁(但此时b锁属于d2线程);当d2线程睡眠时间到,同样会想得到a锁(但此时a锁属于d1线程);,结果造成:d1占着a锁,让d2给它b锁,而d2占着b锁,让d1给它a锁,各不相让,造成死锁!
      

  6.   

    我的看法是:在run()里, 对象从新赋值,已不是原来同步函数里的那个对象了. 
    楼主可以在"  a = new Integer(a.intValue()+1);"
    加一句:  "System.out.println(" after \" a = new Integer(a.intValue()+1)\" The object a is  :"+a);"
    对象a已经变了,新的对象没有被当作同步函数的锁对象,所以就顺利执行下去了.楼主自己把"  a = new Integer(a.intValue()+1);" 注释掉后,出现死锁情况,也说明这一点.
      

  7.   

        你后来a  b都重新new了,内存地址怎么没变