想象我有几个同步方法的类First
。当一个线程锁定类First
时,它是按每个方法还是按类锁定的?例如,以下代码是否会发生死锁?
public class DeadLockQuestion {
public static class First{
public synchronized void a(){
}
public synchronized void b(){
}
public synchronized void c(){
}
public synchronized void d(){
}
public synchronized void e(){
}
}
public static void main(String... args){
First f = new First();
//This code is run in Thread 1
f.a();
// End
//This code is run in Thread 2 simultanously
f.b();
//End
// We have also Threads 3 & 4 & 5 that invoke c,d and e simultanously
}
}
答案 0 :(得分:3)
你有两个Java锁。一个是Object
锁。另一个是Class
锁定。
object lock
仅锁定对同步非静态函数的访问。和Class lock
仅锁定同步静态函数。
对你来说,它是一个object lock
对象f
。因此,对象f
锁定了所有同步的非静态函数。
由于所有线程都使用相同的对象f
,因此一次只能有一个线程访问您的非静态函数a(), b(),...
。
阅读更多here
does deadlock happen for the following code?
不,在你的情况下不会发生。因为当一个Thread
持有锁时,其他线程无法进入同步函数。DeadLock happens due to resources.
您只有一个对象f
的资源。这里没有死点,因为类First不会锁定另一个对象,并且不会发生循环锁定。死锁需要循环锁定!
一些信息:
答案 1 :(得分:2)
线程发生死锁,而不是方法或类。
死锁的线程也持有锁,但在这种情况下,不可能分辨出哪些锁,因为你没有演示实际的死锁情况(如果两个线程调用f
的同步方法一个通过而另一个等待;死锁至少需要两个锁。)
答案 2 :(得分:1)
要单独锁定每个方法,请在每个方法中使用synchronized块并锁定其他对象。
如果你有一个合适的(并且它应该是最终的,以防止潜在的问题)对象已经在类中,你可以使用它。如果没有创建private final Object aLock = new Object();
然后锁定它,例如:
private final Object aLock = new Object();
public void a() {
synchronized(aLock) {
// Do stuff that needs the lock
}
// do stuff that doesn't need the lock
}
始终按住锁定,但不再需要锁定。
答案 3 :(得分:1)
当a()
是同步方法时,f.a()
字面意思是:
synchronized(f){
f.a();
}
因此,在这种情况下,对象监视器f
将发生锁定。在您的情况下,您将需要第二个对象来创建死锁,我不认为可以使用单个对象监视器创建死锁。典型的死锁模式是当没有维持锁定获取的顺序时,即当这发生在两个不同的线程中时:
synchronized(a){
synchronized(b){
...
}
}
// and
synchronized(b){
synchronized(a){
...
}
}
答案 4 :(得分:1)
首先, 线程 发生死锁,而不是类或方法。
当 循环依赖锁 时会发生死锁。
Thread A ---> locks L1 ---> tries to lock L2
Thread B ----> locks L2 ------> tries to lock L1
Image source: FusionReactor deadlock plugin