每种方法或每个类都会发生死锁吗?
想象一下,我有几个同步方法的Class 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 fa(); // End //This code is run in Thread 2 simultanously fb(); //End // We have also Threads 3 & 4 & 5 that invoke c,d and e simultanously } }
你有两个Java锁。 一个是Object
锁定。 另一个是Class
Lock。 object lock
锁定对同步非静态函数的访问。 和Class lock
仅锁定同步静态函数。 对你来说,它是对象f
上的一个object lock
。 因此,对象f
锁定了所有同步的非静态函数。 由于所有线程都使用相同的对象f
,因此一次只能有一个线程能够访问非静态函数a(), b(),...
在这里阅读更多
does deadlock happen for the following code?
不,在你的情况下不会发生。 因为当一个Thread
持有锁时,其他线程无法进入同步函数。 DeadLock happens due to resources.
您只有一个资源是Object f
。 这里没有死锁的意义,因为类First不会锁定另一个对象,也不会发生循环锁定。 死锁需要循环锁定 !
一些信息:
- java中的同步保证没有两个线程可以执行同步或同时需要相同锁定的同步方法。
- synchronized关键字只能用于方法和代码块。 这些方法或块可以是静态的或非静态的。
- 当线程进入java synchronized方法或阻塞时,它获取一个锁,每当它离开java synchronized方法或阻塞时,它就会释放锁。 即使线程在完成后或由于任何错误或exception而离开同步方法,锁也会被释放。
- 静态同步和非静态同步方法可能同时或同时运行,因为它们锁定在不同的对象上。
有用的来源在这里和这里
死锁发生在线程上,而不是方法或类。
死锁的线程也持有锁,但在这种情况下,不可能分辨出哪些锁,因为你没有演示实际的死锁情况(如果两个线程调用f
同步方法经过而另一个等待;死锁需要至少两个锁)。
要单独锁定每个方法,请在每个方法中使用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 }
只要你需要锁,就可以随时按住锁,但不能再锁。
当a()
是同步方法时, fa()
字面意思是:
synchronized(f){ fa(); }
因此,在这种情况下,对象监视器f
将发生锁定。 在您的情况下,您将需要第二个对象来创建死锁,我不认为可以使用单个对象监视器创建死锁。 典型的死锁模式是当没有维护锁获取的顺序时,即当这发生在两个不同的线程中时:
synchronized(a){ synchronized(b){ ... } } // and synchronized(b){ synchronized(a){ ... } }
首先, 线程发生死锁,而不是类或方法。
当存在锁的循环依赖性时发生死锁。
Thread A ---> locks L1 ---> tries to lock L2 Thread B ----> locks L2 ------> tries to lock L1
图像源:FusionReactor死锁插件