public class MyRunnable implements Runnable {
private Object obj1 = new Object();
private Object obj2 = new Object();
private boolean flag;
public MyRunnable(boolean flag) {
this.flag = flag;
}
public void run() {
if(flag) {
while(true) {
synchronized (obj1) {
System.out.println("true obj1");
synchronized(obj2) {
System.out.println("true obj2");
}
}
}
}
else {
while(true) {
synchronized (obj2) {
System.out.println("false obj2");
synchronized(obj1) {
System.out.println("false obj1");
}
}
}
}
}
}
请问以上是线程死锁吗,为什么一直在运行,没有停止。
第二,为什么在两个Object前面加上static,就会死锁?
------解决方案--------------------
应该不是死锁造成的,应该是你的while一直循环造成的。
你如果把
private Object obj1 = new Object();
private Object obj2 = new Object();
改成
private static Object obj1 = new Object();
private static Object obj2 = new Object();
则肯定会死锁
如果你采用的是如下这种启动线程的方式
new Thread(new MyRunnable(true));
new Thread(new MyRunnable(false));
因为你obj1和obj2都是成员变量,每个对象无需竞争,不存在死锁问题。
而如果你使用的是如下这种启动线程的方式
Runnable r = new MyRunnable(true);
new Thread(r);
new Thread(r);
虽存在对obj1和obj2的竞争,但是获取锁的顺序一致,都必须先得到obj1的锁,然后再申请obj2的锁。
所以不会死锁
所以可以看出,你这个程序根本不可能造成死锁。
------解决方案--------------------
还有调用这个类的代码没贴出来吧?贴出来会解释的更清楚。
先就贴出来的说说吧。
1、因为你的程序:
while(true) {
synchronized (obj1) {
System.out.println("true obj1");
synchronized(obj2) {
System.out.println("true obj2");
}
}
}
是死循环,当然不停地运行喽。
2、没加static的情况:你调用的时候可能创建了两个或者两个以上的MyRunnable对象,由于每个MyRunnable对象里面都有自己的obj1和obj2,而每个对象只是执行了flag为true或者false一种情况,也就是说,true和false所执行的代码分别去获得不同对象里的obj1和obj2,这样不会发生死锁。
但是如果加了static,那么obj1和obj2就变成了类变量,就是全局的,那么不论你创建多少个MyRunnable对象来执行,true和false两种代码都会去获得同一个obj1和obj2,由于true和false获得obj1和obj2的顺序相反,发生死锁的可能性很高!
要想阻止死锁发生,最重要的一点就是:任何地方获得多个锁的顺序都要保持相同。