4

This might have been answered before, but because of the complexity of the issue, I need a confirmation. So I rephrase the question

Question 1 : When a thread enters a synchronized block, the memory barrier will include any fields touched, not just fields of the object that I synchronized on? So if many many objects are modified inside a synchronized block, that's a lot of memory moves between thread memory caches.

Thread 1
object.field1 = "";
synchronized (lock) {
  farAwayObject.field1 = "";
  farAwayObject.evenFarther.field2 = "";
}

Thread 2. assuming thread ordering is correct
synchronized (lock) {
  //thread 2 guaranteed to see all fields above as ""
  //even object.field1 ?
}

Question 2 : Is object.field1 = ""; in thread 1 implicitly part of the happens-before relationship?

I hope it is but It might not. If not is there a trick to make it so without putting it into the sync block? It is hard to reason on the program otherwise and it is not practical to put everything under the synchronized { }.

EDIT: clarification: object.field1 is not volatile and the question is "will thread 2 guaranteed to see the write of thread 1, at least ". My question is about memory visibility. For the sake of the argument, let's say only thread 1 writes to non volatile object.field1.

The question 2 can be rephrased as

"Will a synchronized block on a lock push changes made before to be seen by other threads synchronizing on the same lock? "

2
  • The answer is yes to both questions. Commented Feb 8, 2017 at 7:38
  • @shmosel I had the understanding that object.field1 would not be a part of happens-before and Thread2 may or may not see the update? Commented Feb 8, 2017 at 7:39

3 Answers 3

3

1) When a thread enters a synchronized block, the memory barrier will include any fields touched, not just fields of the object that I synchronized on?

Correct. (Assuming that thread 1 and thread 2 synchronize on the same lock.)

So if many many objects are modified inside a synchronized block, that's a lot of memory moves between thread memory caches.

Potentially, yes. However, it is (probably) not movement between caches. More likely, it is a movement from one processor's cache to memory, and from memory to a second processor's cache. Of course, that depends on how the hardware implements the memory hierarchy.

2) Is object.field1 = ""; in thread 1 implicitly part of the happens-before relationship?

There is a chain of happens-before relations

  1. The write to object.field1 happens before the lock is acquired.
  2. That happens before the writes to farAwayObject and so on.
  3. That happens before the lock is released by thread 1
  4. That happens before the lock is acquired by thread 2
  5. That happens before thread 2 reads object.field1.

The problem is what happens if there is an intervening write to object.field1, either before the lock is acquired by thread 1, or by some other thread. In either of those cases, the happens-before chain is not sufficient to ensure that thread 2 sees the value that was written by thread 1.

Sign up to request clarification or add additional context in comments.

1 Comment

can you clarify in the light of my clarification. assume there are no intervening writes. Would you answer yes like shmosel?
2

When a thread enters a synchronized block, the memory barrier will include any fields touched, not just fields of the object that I synchronized on

Assuming that the fields of farAwayObject and evenFarther are always modified and accesed by obtaining a lock on the same object all around your application, all threads will always see the updates made to farAwayObject and evenFarther since synchronized enforces a happens-before condition.

//thread 2 guaranteed to see all fields above as ""

The same cannot be said for object.field1 without knowing how it was declared. Assuming that field1 is a reference not marked as volatile, it will not be a part of the happens before relationship and threads may see stale values for it.

I hope it is but It might not. If not is there a trick to make it so without putting it into the sync block?

Yes. Mark object.field1 as volatile.


Addresing your edit :

The question 2 can be rephrased as

"Will a synchronized block on a lock push changes made before to be seen by other threads synchronizing on the same lock? "

AFAIK the answer is Yes, provided that the writing threads acquire the lock before the reading threads. Unfortunately, this is something you generally can't guarantee and that's why object.field1 needs to be marked as volatile or the statement needs to moved inside the synchronized block.

Take a look at JSR 133 which talks about the cache being flushed to main memory when the thread exits a syncronized block. This should clarify things further.


8 Comments

see my clarifaction. If i don't want to set object.field1 as volatile. isn't the specific write of thread1 to object.field1 pushed to main memory when the synchronized(lock) is executed? If no. would that mean the JVM flags memory changes made under a synchronized lock? so as to only push those changes?
@Mordan See edit. Does that make things more clear? Let me know if it needs further clarification.
your link answered my question apparently. It is a yes. I am relieved. :) I have been searching the web for weeks but never found it. Great link ! thank you.
@Mordan Glad to be of help. I believe my answer would have made more sense quickly if I spoke about the synchronized block flushing caches on exit before I spoke about anything else. By yes, do you mean that other threads will always see the updated value of object.field?. That's not true as explained in my answer.
By yes.. Provided no other threads write to it, Thread 2 will always see "" in object.field because it synchronized on the same lock. Your link provided another gems. "Writing to a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire. In effect, because the new memory model places stricter constraints on reordering of volatile field accesses with other field accesses, volatile or not, anything that was visible to thread A when it writes to volatile field f becomes visible to thread B when it reads f."
|
1

the memory barrier will include any fields touched, not just fields of the object that I synchronized on?

Yes.

Is object.field1 = ""; in thread 1 implicitly part of the happens-before relationship?

Yes, even if it is not volatile.


The happens-before order is a partial order.

The happens-before order is given by the transitive closure of synchronizes-with edges and program order. It must be a valid partial order: reflexive, transitive and antisymmetric.

(JLS 17.4.7)

Actions before a synchronization edge (i.e. The release of the synchronized lock) are ordered by program order and thus synchronized with the release. Transitivity says that actions that are ordered by an acquire of the same lock in another thread therefore has a happens-before order with both the release of that lock AND the actions preceding the release of that lock, whether or not it is inside the body of the synchronized block. The important thing to remember about this is that ordering occurs on actions (i.e. Acquire/release of a lock) not a block such as implied by the brackets of the synchronized keyword. The brackets indicate the position of the acquire/release actions as well as where a set of actions cannot be interleaved.

Finally, remember that happens-before is a "partial" order. It means:

  1. Happens before enforces memory consistency when actions happen to come in the particular order (i.e. release/acquire, write/read, etc)
  2. Happens before depends on stronger guarantees such as program order to produce the correct functionality.
  3. Happens before does not prevent errors coming from interleaving of nonatomic actions
  4. Happens before is the transitive relationship between the action and a strong action. (You can put the read of your shared variable outside the synchronized block as long as the write comes before the block and the read comes after the block). Stronger ordering guarantees also follow happens before ordering, but they also provide additional effects described in the spec.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.