Robin Kreuzer
Robin Kreuzer

Reputation: 180

one java memoryFlushing volatile: A good programdesign?

its a related question to this one: java: using volatile at one variable VS each variable

i have one or more different objects. i want to change some state in it and then i want to make that state visible to other threads.

For performance reasons i dont want to make each member variable in that objects volatile. And sometimes i want to use these objects in a single thread application. So in that case the volatile would be also bad.

So i had the following:

//these following mehtods change some internal variable state. These variables are not volatile or synchronized

boolean volatile memoryFlusher=false;

Thread1:

obj1->changeSomeState();
obj1->changeMoreState();
obj2->alsoSomeStateChange();

//and now i want to make that state visible to others

memoryFlusher=false; //volatile write


Thread2:

boolean tmp=memoryFlusher; // volatile read but variable is not used again

obj1->getState();
obj2->getState();

So till now its more or less the same to my related question i linked at the beginning.

So now i want to ask the following:

My memoryFlusher is not optimzed away? (unanswerd in my other question) Each volatile write/read flushes all memoryState of ALL? other (also none-volatile-)variables?

And now the really new question:

is that a good design, i do there? Cause i didnt saw any code anywhere like this, i posted here.

Should i program my Progamm in a other way? Is there a other best practise to increase the performance and getting visibilty? Is there other best practise in the program-design view, not having doing something like this?

Edit:

the state i change is unreleated. So i want with that memory-variable one memoryflusher, and no lock mechanism. It should replace a lot of single volatile variable to one. somewhere i dont need that explicit volatile memoryFlushing cause i use a synchronized, for example

synchronized(x)
{
    ...
    obj1->stateChange() //if internally is used a volatile, then i have a volatile memory flush and later the synchronized-end memory-flush, i guess (is that right?)
    ...
}

That would be one example, where it could be useful?!

summary: But is that correct, in that way i think using that memoryFlushing?

Upvotes: 3

Views: 115

Answers (2)

John Vint
John Vint

Reputation: 40256

My memoryFlusher is not optimzed away?

No, the write to and read from memoryFlusher will not be optimized away.

Each volatile write/read flushes all memoryState of ALL

Yes, it will synchronize memory to both threads. However, it only works if you can detect the change from one thread to another.

In your example, you read memoryFlusher, but memoryFlusher is false on initialization. How do you know Thread-1 actually wrote to it? What if, Thread-1 is at this line obj1 -> changeMoreState, and Thread-2 reads memoryFlusher. Both values would be false here and so you don't know if Thread-1 actually completed.You are out of sync as you haven't established your happens-before ordering.

To correct your code, you should write true to the memoryFlusher field and Thread-2 should only continue if memoryFlusher is true. This effectively establishes your ordering, but it also makes your code more confusing.

I'd suggest using a StampedLock instead of trying this. The StampedLock gives you really fast reads when writes are not going to be frequent.

Upvotes: 2

Matt Timmermans
Matt Timmermans

Reputation: 59144

Your volatile reads and writes are not optimized away, but I don't see any use for this code. That's probably why you don't see it elsewhere. You didn't say what you expect from it, though, so who knows?

It looks like you want to make sure that Thread2 reliably reads the state changes made by Thread1. Well, that works only if you are sure that the code in Thread2 actually runs after the code in Thread1.

How do you know that that is the case?

I suggest that if there is really any way you can be sure that the Thread2 code happens after the Thread1 code, then there is already a memory barrier in place that establishes this fact, and renders your volatile variable unnecessary.

Upvotes: 2

Related Questions