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 不是应该各自只拿到一个吗?
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 不是应该各自只拿到一个吗?
首先你要明白 synchronized(object) 这个意思,也就是在这个代码块里面,同时只有一个执行。
你的程序是两个程序了,不是同一块代码块。是两个类里面的代码,锁毛啊。
object不是锁。他只是钥匙。如果你想用说,就用reenlock的lock显式的调用。
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。谁能解释一下。
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锁,各不相让,造成死锁!
楼主可以在" 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);" 注释掉后,出现死锁情况,也说明这一点.