是否可以在多个线程之间共享一个对象来模拟Java死锁场景?
例如我有一个班级
public class MyClass {
public synchronized void syncInstanceMethod1(){
/// Anything here to simulate a dead lock
}
public synchronized void syncInstanceMethod2(){
/// Anything here to simulate a dead lock
}
public static synchronized void syncStaticMethod1(){
/// Anything here to simulate a dead lock
}
public static synchronized void syncStaticMethod2(){
/// Anything here to simulate a dead lock
}
public void instanceMethod1(){
/// Anything here to simulate a dead lock
}
public void instanceMethod2(){
/// Anything here to simulate a dead lock
}
public static void main(String[] args) {
MyClass shared = new MyClass(); // Allowed to create only one instance
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// Do whatever here to simulate dead lock like calling various methods on the shared object in any order
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
// Do whatever here to simulate dead lock like calling various methods on the shared object in any order
}
});
// Allowed to create more threads like above. t3 , t4 etc...
t1.start();
t2.start();
}
}
可能是不可能的。由于可能发生死锁的常见情况是代码块,它获取锁定一个对象而不释放它尝试获取另一个对象的锁定。
我们可以通过调用静态同步方法从同步实例方法之一模拟这种情况,即尝试锁定'类'同时按住锁定对象'这个'。但是为了发生僵局,我们需要在其他地方以相反的顺序出现类似的情况。
另外,由于静态方法无法访问这个'它无法锁定这个'而且两个同步的实例方法不能同时运行,这些东西让人相信我们无法在这里模拟死锁。我是对的吗?
答案 0 :(得分:2)
虽然您已被要求仅创建一个实例,但线程仍有两个锁可以争用。实例方法需要一个线程来获取MyClass
对象实例上的锁,即shared
或this
,具体取决于您的查看方式。
另一方面,静态方法需要一个线程来获取MyClass.class
类对象实例上的锁;你从this.getClass()
得到的那个。
因此,如果线程A已经在执行同步实例方法(对this
具有锁定)并尝试进入其中一个同步静态方法,而另一个线程B也已经在执行静态方法(锁定MyClass.class
),现在尝试在同一个 MyClass
对象上输入同步实例方法,将发生死锁。
这是一些模拟此场景的代码。
public class SingleObjectDeadlock {
public synchronized void syncInstanceMethod1() {
System.out.println("In syncInstanceMethod1()");
syncStaticMethod2();
}
public synchronized void syncInstanceMethod2() {
System.out.println("In syncInstanceMethod2()");
}
public static synchronized void syncStaticMethod1(SingleObjectDeadlock shared) {
System.out.println("In syncStaticMethod1()");
shared.syncInstanceMethod2();
}
public static synchronized void syncStaticMethod2() {
System.out.println("In syncStaticMethod2()");
}
public static void main(String[] args) {
SingleObjectDeadlock shared = new SingleObjectDeadlock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
shared.syncInstanceMethod1();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
SingleObjectDeadlock.syncStaticMethod1(shared);
}
});
t1.start();
t2.start();
System.out.println("DEADLOCK!");
}
}
运行后,您会发现死锁并且程序永远不会打印
In syncStaticMethod2()
In syncInstanceMethod2()
答案 1 :(得分:1)
我第一次阅读时误解了你的问题。但是如果共享实例不在静态同步方法的范围内(比如带有静态变量的引用),那么您将无法先在静态上锁定,然后在共享实例上锁定,因为它&# 39;不在范围内,不能锁定或调用它。
我想我不知道你的作业中允许了什么,这有点令人困惑。