Multi thread Memory Visibility inside Synchronized keyword

I am using multiple threads… To better understand an issue, I need an answer to this rethorical question

I posted it on stack

I have two classes.

One class is just a container for a integer value with get and set synchronized methods.

public class Sync {
private int dataSync;

public synchronized int getDataSync() {
return dataSync;
}

public synchronized void setDataSync(int data) {
dataSync = data;
}
}

The other classes is similar. It is just a container for a integer value with get and set methods without synchronization.

public class NotSync {

private int dataNotSync;

public int getDataNotSync() {
return dataNotSync;
}

public void setDataNotSync(int data) {
dataNotSync = data;
}
}

Now my rhetorical question is “is 10 value guaranteed to be visible to all other threads” at the end of the run method.

public class RunSync {

public static void main(String[] args) {
RunSync rs = new RunSync();
rs.run();
}

private NotSync dataNS;

private Sync dataS;

public RunSync() {
dataS = new Sync();
dataNS = new NotSync();
}

public synchronized void run() {
dataS.setDataSync(45);
dataNS.setDataNotSync(10);
//Question A: is 10 value guaranteed to be visible to all other
//threads when method exits?
//we are inside a synchronized block aren’t we?
//so all writes must be flushed to main memory
}
}

Synchronization has nothing to do with visibility.

The only thing your synchronized methods guarantee is that they can’t be called by two different threads at the same time.

You aren’t even using threads, so this is a non-issue.

By the way, a rhetorical question is a question that you don’t expect an answer to. Maybe you meant hypothetical question?

[quote=“Mordan,post:1,topic:57869”]
Nope, it isn’t.

The synchronized keyword on the SunSync’s run() method also won’t help you here. If other threads would, however, synchronize with that RunSync instance, it would be properly synced between threads.

I am trying to wrap my head about it. In my gaming engine, Render State is shared between threads. It is a HEADACHE!

http://gee.cs.oswego.edu/dl/cpj/jmm.html

Visibility is a matter. Threads may update stuff and that stuff stays in the CPU cache and the main memory is not updated.

I bolded the most relevant condition for true visibility. There is of course the volatile keyword as well.

I can’t quote it all. The forum won’t let me.

[quote]Visibility
Changes to fields made by one thread are guaranteed to be visible to other threads only under the following conditions:

A writing thread releases a synchronization lock and a reading thread subsequently acquires that same synchronization lock.

In essence, releasing a lock forces a flush of all writes from working memory employed by the thread, and acquiring a lock forces a (re)load of the values of accessible fields. While lock actions provide exclusion only for the operations performed within a synchronized method or block, these memory effects are defined to cover all fields used by the thread performing the action.

[/quote]

Look up “memory barriers”.

Cas :slight_smile:

Any reader thread will not be guaranteed to see the 10, because they do not really synchronize with the writing thread, and therefore a reading thread may read the value before main() is called.
In other words: The writing and the reading thread must synchronize on the same object in order to establish a happens-before relation (including memory visibility).

Read: https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5

I understand that thank you. The happens before. But my concern is the synchronize flushes back to memory.
Imagine there is a field
public volatile boolean was10Written = false;

This field is accessible by any thread

now I modify the method to

public synchronized void run2() {
dataNS.setDataNotSync(10);
was10Written = true;
}

Will the 10 be visible to other threads checking on was10Written as true?

I want to know if synchronize flushes back to main memory when statement closes. From the answers I got, it seems the answer is no but maybe. It will only be guaranteed to flush back when another lock is aquired. That would make sense from the performance implementation point of view. This prevents the JVM from flushing everytime a sync statement closes.

rhetorical

G2y8Sx4B2Sk

This is insane. I am not so sure I can deal with the multi thread engine. I wanted 3 threads. 1 for user input, 1 for simulation, 1 for rendering. And I don’t want to put the synchronized keyword on every single method.

I am educating myself right now.

Just a few links for the record.

http://lmax-exchange.github.io/disruptor/

Dissecting the Disruptor: Demystifying Memory Barriers

Usually you can greatly simplify inter-thread communication by using queues (like ArrayBlockingQueue).

You might want to, specifically, look at SPSC (Single Producer, Single Consumer) Queues and just create queues for each of the interchanges. Nitsan, an awesome guy btw, has a nice set of highly optimized implementations for various situations: https://github.com/nitsanw/JCTools