Skip to content
Advertisement

Does a synchronized block trigger a full memory fence for arrays?

I am confused about sharing arrays safely between threads in Java, specifically memory fences and the keyword synchronized.

This Q&A is helpful, but does not answer all of my questions: Java arrays: synchronized + Atomic*, or synchronized suffices?

What follows is sample code to demonstrate the issue. Assume there is a pool of worker threads that populates the SharedTable via method add(...). After all worker threads are done, a final thread reads and saves the data.

Sample code to demonstrate the issue:

JavaScript

The sample code above could also be implemented using Atomic*Array, which acts as an “array of volatile values/references”.

JavaScript
  1. Is SharedTable thread-safe (and cache coherent)?
  2. Is SharedTable (much?) more efficient as only a single memory fence is required, whereas SharedTable2 invokes a memory fence for each call to Atomic*Array.set(...)?

If it helps, I am using Java 8 on 64-bit x86 hardware (Windows and Linux).

Advertisement

Answer

No, SharedTable is not thread-safe. A happens-before is only guaranteed if you read, from a synchronized block, something that has been written from a synchronized block using the same lock.

Since the writes are made out of a synchronized block, the JMM doesn’t guarantee that the writes will be visible by the reader thread.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement