0

Immagine that I have Class First with several synchronised methods. When a thread locks the class First, does it lock per method or per class? For example does deadlock happen for the following code?

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

    }

}
Johnny
  • 1,509
  • 5
  • 25
  • 38

5 Answers5

3

You have got two locks in Java. One is Object lock. and the other is Class Lock. The object lock locks access to synchronized non-static functions only. and Class lock locks on synchronized static functions only. For you, its an object lock on object f. So all the synchronized non-static functions are locked for object f. Since all the Threads are using the same object f, Only one Thread will be able to access your non-static functions a(), b(),... at a time. Read more here

does deadlock happen for the following code?

No, it won't happen in your case. Because While one Thread is holding the lock, Other threads can't get inside your synchronized function.DeadLock happens due to resources.
You have only one resource thats Object f. There's no point of a dead-lock here because the class First doesn't lock another object and no cyclic lock can happen. Deadlock requires a cyclic lock!

Some Info:

  1. Synchronization in java guarantees that no two threads can execute a synchronized method which requires same lock simultaneously or concurrently.
  2. synchronized keyword can be used only with methods and code blocks. These methods or blocks can be static or non-static both.
  3. When ever a thread enters into java synchronized method or block it acquires a lock and whenever it leaves java synchronized method or block it releases the lock. Lock is released even if thread leaves synchronized method after completion or due to any Error or Exception.
  4. It’s possible that both static synchronized and non static synchronized method can run simultaneously or concurrently because they lock on different object.
    Useful Source Here, and here
Ananth
  • 2,597
  • 1
  • 29
  • 39
Aman Arora
  • 1,232
  • 1
  • 10
  • 26
  • So what should I do if I want to be able to lock f by method where I can't make f methods static? And anyway, having such a structure can't result in deadlock? – Johnny Dec 19 '13 at 10:46
  • @Johnny i din't get your question. Can you explain? – Aman Arora Dec 19 '13 at 10:50
  • You can do this `public synchronized void a(){ synchronized(DeadLockQuestion .class){//code here} }`. Is this what you meant ? – Aman Arora Dec 19 '13 at 10:52
  • I think Tim B has given the answer of this comment. It should be in the way he says 'public void a(){ synchronized(object){//code goes here} }' – Johnny Dec 19 '13 at 10:55
  • Please go through [this](http://howtodoinjava.com/2013/03/08/thread-synchronization-object-level-locking-and-class-level-locking/) once. It will be helpful. Because Tim B is also locking on `objects` and its different than `Class Level Locking`. :) – Aman Arora Dec 19 '13 at 10:58
  • It's very difficult to me to select the exact best answer for this question. look at the answer of Andrey Chaschev, it shows what synchronised methods. For the comment I'd made Tim B has answered. But generally as you, Narendra Pathai and the others have told, deadlock can't happen for this code. – Johnny Dec 19 '13 at 11:03
2

Deadlock happens to threads, not to methods or classes.

The deadlocked threads also hold locks, but in this case it is impossible to tell which locks because you do not demonstrate an actual deadlock scenario (if two threads call synchronized methods of f one goes through and the other waits; deadlock requires at least two locks).

Lorenzo Gatti
  • 1,260
  • 1
  • 10
  • 15
1

To lock each method independently use a synchronized block within each method and lock on a different object.

If you have an appropriate (and it should be final to prevent potential problems) object already within the class you can use that. If not create a private final Object aLock = new Object(); and then lock on that, for example:

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
}

Always hold the lock for as long as you need it, but no longer.

Tim B
  • 40,716
  • 16
  • 83
  • 128
1

When a() is a synchronized method, f.a() literally means:

synchronized(f){
    f.a();
}

So in this case a lock would happen for object monitor f. In your case you would require a second object to create a deadlock, I don't think it's possible to create a deadlock with a single object monitor. A typical deadlock pattern is when an order of lock acquisition is not being maintained, i.e. when this happens in two different threads:

synchronized(a){
     synchronized(b){
         ...
     }
}
// and
synchronized(b){
     synchronized(a){
         ...
     }
}
Andrey Chaschev
  • 16,160
  • 5
  • 51
  • 68
1

Firstly, Deadlock occurs with threads and not classes or methods.

Deadlock occurs when there is a cyclic dependency of locks.

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

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120