此代码是否可以通过线程1调用one
和线程2调用two
死锁。也就是说,能否将内部锁的获取重新排序到获取外部锁之前(从另一个线程的POV)?
private final Object foo = new Object();
synchronized void one() {
// ...
synchronized(this.foo) {
// ...
}
// ...
}
synchronized void two() {
// ...
synchronized(this.foo) {
// ...
}
// ...
}
答案 0 :(得分:0)
不,这不会死锁。
调用同步方法时,this
的固有锁定在执行方法主体之前被锁定。在这里,线程1或线程2将开始运行其方法,而另一个线程将无法锁定this.foo
的固有锁定,因此this
的锁定所有者将能够锁定this.foo
。
答案 1 :(得分:0)
使用简单测试即可:
class LockTest implements Runnable {
public final Object foo = new Object();
boolean runOne;
public LockTest(boolean runOne) {
this.runOne = runOne;
}
synchronized void one() {
System.out.println("runnin one function");
synchronized(this.foo) {
try {
System.out.println("Enter Sleep function one");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized void two() {
System.out.println("running two function");
synchronized(this.foo) {
try {
System.out.println("enter sleep function two");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
if(runOne)
one();
else
two();
}
}
在主类中使用它:
while (true)
{
LockTest document2 = new LockTest(true);
LockTest document3 = new LockTest(false);
Thread tread1 = new Thread(document2);
Thread tread2 = new Thread(document3);
tread1.start();
tread2.start();
a++;
if(a==10)
break;
}
我们没有锁定,甚至没有通过线程转储观看一切正常。为什么?因为每次我们都用一个新的对象foo初始化一个新的线程。但是,如果将该对象声明为静态对象,则它将是一个锁,其他线程需要等待。所以从我的测试和POV来看。不,它不能陷入僵局。