views:

249

answers:

2

I just need a confirmation that i have understood the concept of locks in synchronized blocks correctly. First I will tell what I have understood. Acquiring a lock of an object means that no other thread can access the synchronized code of the object's class. In case of synchronized methods, Threads acquire lock on the object used to invoke the method(i.e., implicitly the this reference). That means the other threads cannot access the synchronized code of the class of the current object. But, in case of synchronized blocks we can specify the object on which we want the thread to acquire the lock.

Now lets say we have synchronized block in a method in class A acquiring a lock on object of class B. So lets say one thread enters this synchronized block and has acquired the lock of a particular object of class B.

If any other thread uses the same object of class B it will not be able to enter the synchronized block in class A, right? And also the other threads cannot also access any synchronized code in class B?

And what about the other synchronized code in class A? Because the thread has acquired lock on the object of class B, the other threads can access the other synchronized code of class A or not? This means there is no lock on the object of class A as such, only class B?

I hope people understand my questions.

Thanks in advance.

+2  A: 

Acquiring a lock of an object means that no other thread can access the synchronized code of the object's class.

This is not strictly true. Another thread can execute synchronized code belonging to the object's class if the code synchronizes on a different object instance. The lock only restricts threads that are synchronizing on the same instance.

Now, if you are talking about a synchronized (non static) method, then the object that will be locked is the this for the called method. But the same rules apply.

Now lets say we have synchronized block in a method in class A acquiring a lock on object of class B. So lets say one thread enters this synchronized block and has acquired the lock of a particular object of class B.

If any other thread uses the same object of class B it will not be able to enter the synchronized block in class A, right? And also the other threads cannot also access any synchronized code in class B?

The first part is correct if the "other thread" is synchronizing on the same instance of B. Otherwise it is incorrect.

The second part is incorrect. It is only code that synchronizes on the same instance of B that is blocked.

Stephen C
"It is only code that synchronizes on the same instance of B that is blocked."So you mean the code in class A synchronized on object of class B will be blocked. And if class B itself has synchronized code, it will not be blocked? I have this question because it is the lock of object of class B that we are acquiring. That lock should block the synchronized code in calss B also. Isn't it?
TheCoolestSid
No. I mean that will only be blocked if it synchronizes on the same B object. The point is that the location of the code is irrelevant; the *only thing that matters* is the object that you are synchronizing on.
Stephen C
Alright. So if a thread has acquired the lock on an object all the code synchronized on that object will be blocked any where the code might be.
TheCoolestSid
That's it exactly.
Stephen C
Thank You Stephen!
TheCoolestSid
+1  A: 

First, I think you would be better off taking the word class out of the conversation. Let's assume that you have two objects o1 and o2, that are instances of classes that are actually irrelevant to the discussion, and that o1 has a reference to o2.

If o1 synchronizes a block on instance o2 then no other thread can enter a synchronized section on the same instance o2. That could be either a non-static synchronized method of o2 or any synchronized block that requests a lock on the same object (assume there is an o3 object that also has a reference to o2 and wants to synch on it, it would be blocked until o1 releases the lock).

What might be confusing to you is the syntactic sugar around synchronized methods. A synchronized method is just a method for which the compiler adds a synchronized block on the actual instance you are calling the method upon, that covers the whole method body.

public synchronized void synch1() {
   // body
}
// equivalent to:
public void synch2() {
   synchronized( this ) {
      // body
   }
}

If you always think in terms of synchronized blocks and the actual instance that is being used as a lock, things seem to me as simpler. A thread can lock on any object, two threads cannot have access to synchronized regions locked by the same object.

David Rodríguez - dribeas