Reputation: 2698
I read that the synchronized
method or block provides two features: "mutual exclusion" and "visibility". I want to know two things.
public class A{
private final Object lock = new Object();
private C obj = new C();
public void methodA(){
synchronized(lock){
obj.x = 1;
obj.y=3;
}
}
public void methodB(C obj2){
synchronized(lock){
obj2.x = obj.x;
}
}
}
Let's assume that we have 2 threads that called methodA
on a global shared object of type A
, and the lock
is acquired by thread1
, now after thread1
release the lock
. now the visibility is that all other thread will read the changes to obj
? I.e. will every change inside the synchronized
block be visible? Or should I change C object to volatile
to make it change visible to others?
Upvotes: 1
Views: 125
Reputation: 34920
No, accessing to obj
fields is still not thread-safe. Synchronization on the lock object only allows you thread-safe operations for writing values to obj
's fields in this block.
UPD: volatile
for obj
will not help you, because you don't change this field's own reference value.
Upvotes: 0
Reputation: 272437
Making obj
volatile
will make the reference to the C object volatile
. i.e. visible outside the synchronised block. It won't affect the members of that object.
i.e. a reassignment to obj will be visible to another thread. A reassignment to its members won't.
Upvotes: 2
Reputation: 328923
is every thing change inside the synchronized block will be visibile?
Yes that's the idea. The JLS 17.45 defines happens before relationships. In particular:
An unlock on a monitor happens-before every subsequent lock on that monitor.
So when thread2 acquires the lock, you have the guarantee that it will see the changes made by thread1 while holding that same lock.
Should I change C object to volatile to make it change visible to others?
volatile guarantees that if you write: obj = new C();
somewhere, a subsequent read of obj
will see that it now refers to a new object. However, it does not provide any such guarantee with regards to the "content" of obj. So if you write: obj.x = someValue;
, with obj being volatile, you don't have a guarantee that the change will be visible to another thread. Unless you make x
volatile too.
Upvotes: 1
Reputation: 1806
To answer your question, another method can simply give you access to the variable obj, without the lock too. What you have to ensure is that all accesses to obj must be guarded carefully through locks, so that obj is not in an inconsistent state (as defined by a programmer).
In your particular example, it looks consistent enough to me.
Upvotes: 0
Reputation: 533930
now the visibility is that all other thread will read the changes to obj ?
Only threads inside a synchronized block for that lock.
is every thing change inside the synchronized block will be visibile ?
Only probably. For guarenteed visibility the thread has to be inside a synchronized block.
or i should change C object to volatile ?
It will not help if you didn't have synchronized and will not make any difference here. volatile
will only changes the behaviour of the obj
reference, not it's fields.
Upvotes: 1