user4o01
user4o01

Reputation: 2698

Java concurrency issue about visibility

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

Answers (5)

Andremoniy
Andremoniy

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

Brian Agnew
Brian Agnew

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

assylias
assylias

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

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

Peter Lawrey
Peter Lawrey

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

Related Questions