Java takes place before / after the memory model. There must be some kind of general parallel construction (e.g., a synchronized block / method, lock, volatile, atomic) both in the write path and in the read path in order to cause this behavior.
If you synchronize both methods, you create a lock for the entire object that will be used by both read and write streams. The JVM ensures that any changes that occur in the write stream that occur before exiting the (synchronized) setInt method are visible to any read streams after they enter the (synchronized) getInt method. The JVM will introduce the necessary memory barriers for this to happen.
If only the write method is synchronized, changes to the object may not be visible to any read stream. This is because the read path that the JVM can use to make sure that the visible memory of the read stream (cache, etc.) matches the write stream does not exist. Make sure the getInt method is synchronized.
Note: in this case, changing the volatility of the "number" of the field will give the correct behavior, since volatile read / write also provides the same behavior of memory visibility in the JVM, and the action inside the setInt method is just the destination.
Michael barker
source share