死锁和同步方法 [英] Deadlocks and Synchronized methods
问题描述
我在Stack Overflow上找到了一个代码,我认为它与我所面临的非常相似,但我仍然不明白为什么会进入死锁状态。该示例来自 Java中的死锁检测:
I've found one of the code on Stack Overflow and I thought it is pretty similar to what I am facing but I still don't understand why this would enter a deadlock. The example was taken from Deadlock detection in Java:
Class A
{
synchronized void methodA(B b)
{
b.last();
}
synchronized void last()
{
System.out.println(" Inside A.last()");
}
}
Class B
{
synchronized void methodB(A a)
{
a.last();
}
synchronized void last()
{
System.out.println(" Inside B.last()");
}
}
Class Deadlock implements Runnable
{
A a = new A();
B b = new B();
// Constructor
Deadlock()
{
Thread t = new Thread(this);
t.start();
a.methodA(b);
}
public void run()
{
b.methodB(a);
}
public static void main(String args[] )
{
new Deadlock();
}
}
在这种情况下,当Deadlock()构造函数是它被称为一个线程。执行此操作时,将调用run()方法。它将调用b.methodB(a),然后调用a.last()来打印出一个语句。同时,a.methodA(b)将调用b.last()。任何对象都没有交叉依赖关系,并且它们也没有同时执行方法。即使它们是,synchronized参数关键字也会排队,不是吗?但是,为什么偶尔也会陷入僵局呢?它不是所有的时间,但它有时会陷入僵局,这是非常不可预测的。是什么导致这种情况陷入僵局和变通方法?
In this case, when the Deadlock() constructor is called, it starts itself as a thread. When it does this, the run() method is invoked. It will call b.methodB(a), which then calls a.last() to just print out a statement. At the same time, a.methodA(b) would call b.last(). There is no cross dependencies on any object and they are not executing a method at a same time too. Even if they are, the synchronized keyword would queue them, wouldn't it? But how come this would occasionally enter a deadlock too? It is not all the time but it would sometimes enter a deadlock, which is quite unpredictable. What is it that causes this to go into a deadlock and workarounds?
推荐答案
这两个陈述的执行可能是交织:
It is possible that the execution of these two statements is interweaved:
Thread 1: a.methodA(b); //inside the constructor
Thread 2: b.methodB(a); //inside run()
执行 a.methodA()
,线程1需要获取 A
对象的锁定。
to execute a.methodA()
, Thread 1 will need to obtain the lock on the A
object.
执行 b.methodB()
,线程2需要获取 B
对象的锁定。
to execute b.methodB()
, Thread 2 will need to obtain the lock on the B
object.
对于线程1的方法A()
然后能够在 b $ c上调用sychronized方法$ c>实例,它需要获取线程2持有的
b
的锁,这将导致线程1等待,直到释放该锁。
For Thread 1's methodA()
to then be able to call the sychronized method on the b
instance, it will need to obtain the lock on b
being held by Thread 2, which will cause Thread 1 to wait until that lock is freed.
对于Thread2的 methodB()
,可以在 a $ c上调用synchronized方法$ c>实例,它需要获取由线程1保存在
a
上的锁定 - 这将导致线程2也等待。
For Thread2's methodB()
to be able to call the synchronized method on the a
instance, it will need to obtain the lock being held on a
by Thread 1 - which will cause Thread 2 to wait as well.
由于每个线程都持有另一个线程想要的锁,因此会发生死锁,其中任何一个线程都无法获得所需的锁,并且两个线程都不会释放该loc 持有的ks。
Since each thread is holding a lock that the other thread wants, a deadlock will occur where neither thread is able to obtain the lock it wants, and neither thread will release the locks that it does hold.
重要的是要理解这段代码在运行它时不会产生死锁 - 只有当四个关键步骤(Thread1持有A的锁并试图获得B,其中线程2持有B的锁并尝试获得A)时,按特定顺序执行。运行此代码足够多次,但订单肯定会发生。
It's important to understand that this code will not produce a deadlock 100% of the time you run it - only when the four crucial steps (Thread1 holds A's lock and tries to obtain B, which Thread 2 holds B's lock and tries to obtain A's) are executed in a certain order. Run this code enough times and that order is bound to happen though.
这篇关于死锁和同步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!