每种方法或每个类都会发生死锁吗?

时间:2013-12-19 10:38:57

标签: java multithreading deadlock

想象我有几个同步方法的类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

    }

}

5 个答案:

答案 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. java中的同步保证没有两个线程可以执行 同步或同时需要相同锁定的同步方法 同时进行。
  2. synchronized关键字只能用于方法和代码块。 这些方法或块都可以是静态的或非静态的。
  3. 当线程进入java synchronized方法或阻塞它时 获取一个锁,每当它离开java同步方法或 阻止它释放锁。即使线程离开也会释放锁定 完成后的同步方法或由于任何错误或 异常。
  4. 静态同步和非静态都可能 synchronized方法可以同时或同时运行,因为 他们锁定不同的对象。
    有用的来源Herehere

答案 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

enter image description here