views:

129

answers:

4

I'm new to Java Threads and synchronization.

Lets say I have:

public class MyClass(){

    public synchronized void method1(){ 
        //call method2();
    } 

    public synchronized void method2(){};

}
  1. What does it mean when I synchronize a method1() on an instance object? So when a thread acquired the lock when trying to access the synchronized method1(), does it prevent other threads to access another synchronized method2() from that same object?

  2. Lets say a thread acquires a lock when accessing method1(), but lets say that method1() makes a call to method2() which is also synchronized. Can this be possible? I mean are there any rules that can prevent method1() from calling method2()?

Thanks in advance.

+4  A: 
  1. See here:

    it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

  2. Since this thread holds the lock on the current object, it can invoke method2(), and no other thread can.

Bozho
+7  A: 
  1. Yes, using the synchronized method modifier on a non-static method means that it uses the monitor of the instance the method is invoked on, and this is shared between all such methods.
  2. No - the thread already owns the monitor, so it is free to enter other blocks protected by the same monitor.
Michael Borgwardt
+1  A: 

A note on question 2, method1() can also call synchronized methods also in other classes which could cause a deadlock:

Thread1 calls synchronized method1() which in turn needs to call synchronized method_b() in AnotherClass Thread2 holds the lock on AnotherClass and is executing a method that needs to call method1() in the class whose lock is held by Thread1

Both Threads will block waiting for the other to free the lock, a deadlock.

Cleber Goncalves
+2  A: 

(1) This is equivalent to:

public void method1(){ 
    synchronized (this) {
        ...
    }
}

So it synchronizes on the current instance. If we rewrite method2 in the same way...

public void method2(){ 
    synchronized (this) {
        ...
    }
}

... then you can clearly see that they lock on the same object and thus other threads could not call method1 or method2 until method1 exits its synchronized block.

(2) synchronized blocks are re-entrant, meaning that the same thread can enter other synchronized blocks that lock on the same object as many times as it wants. As I understand it, every time you enter a synchronized block, Java increases a counter on the object you are synchronizing on by 1, and every time you exit a synchronized block, it decreases it. When that counter reaches 0, the lock is released.

cdmckay