Reputation: 55
Good afternoon!
Inside class B, a method is defined using the keyword "synchronized". Inside this method, you work with an object of class A, which is publicly available. Tell me, please, is thread safety guaranteed for object A in this case? I.e. synchronized will be applied to a separate instance of B, not focusing on A - "synchronized(this { } == synchronized(B) { }"? For greater thread safety, is it necessary to use a block of the type "synchronized(A) { }"?
The question is caused by the fact that the first example in practice still does not work thread-safe, although this is the only method of correcting a public object. I'm figuring out why.
Thanks for the reply.
public class B {
public synchronized void updateA(A a) {
....
}
}
public class B {
public void updateA(A a) {
synchronized (this) {
....
}
}
}
public class B {
public void updateA(A a) {
synchronized (a) {
....
}
}
}
Upvotes: 0
Views: 129
Reputation: 27115
None of your examples guarantees "thread safety" for object a
—not even the last one that does its work inside a synchronized(a)...
block.
The problem is, when one thread enters synchronized(a)...
it does not prevent other threads from using a
. The only thing it prevents is, it prevents other threads from synchronizing on the same a
at the same time.
In Java, and in most other programming languages, the only locking available to you is advisory locking. If a true lock is like a physical lock on a door that you need a key to open, then an advisory lock is like a sign hanging on the door that says, "please do not enter." It only works if everybody respects the sign.
If you want some object a
to be "locked," then it is your responsibility to ensure that every place in your entire program* where that same object can be used is inside a synchronized
block and, to ensure that all of those blocks synchronize on the same object. It doesn't matter if they're all synchronized(a)
or synchronized(o)
where o
is some other object. The only thing that matters is that you use the same object for the "lock" in every place where you access the object, a
.
* The best way—the only practical way in the long run—to ensure anything about every place in the program that can touch a
is to make a
a private
member of some class. Whoever controls the class in which a
is private
controls every place where a
can be touched.
Upvotes: 1
Reputation: 1409
Using synchronized
keyword in the method signature means that when one thread use this method it lock monitor on this
object and no other threads can use this method of this instance until first thread release it. It does not lock any other methods or A
object. Only part of code inside synchronized block. So if two separate instances of 'B' modify the same 'a' object it won't be locked.
First and second examples in your question are the same in meaning.
Third example with synchronized (a)
means that for synchronization will be used monitor of the a
object.
synchronized will be applied to a separate instance of B
In your code synchronized
uses different monitors for each instance. To provide synchronization for all instances you need to define common monitor, for example synchronized (B.class)
or synchronized (A.class)
.
For greater thread safety, is it necessary to use a block of the type "synchronized(A) { }"?
If you want to avoid concurrency using of a
object you need to lock on a
.
Upvotes: 0