I have been asked this question in an interview.
What is the similarity between volatile and synchronized. Can a class be made thread safe without using synchonized keyword.
I did some google. The volatile variables can be thread safe as the data is written in the main memory and every thread see updated copy always.
Is my understanding correct? Also I need more details on this. Not able to find any good read for this.
Both volatile and synchronized blocks cause a memory barrier where values are flush from local memory to the central memory store. If your variables are all volatile then accessing and modifying those values is thread safe only you are performing single atomic actions (getting the value or setting the value). If you need to perform multiple accesses or repeated access then just using volatile variables is not enough to prevent inconsistent data. For example you can't loop through a collection safely, nor could you do a calculation which depends on multiple values. The reason is those values could change on you during your loop / calculation based on actions in another thread and this could lead to inconsistent results.
volatile is not replacement of synchronized block. as Steve pointed out you should only use volatile variable to set or get (not get and set).
as rule of thumb, in most cases, you should use volatile in an environment where only one thread update that variable.
both used for memory visibility. but volatile is weak there ...
<edit>volatile dont acquire object lock</edit>
Steve Luke wrote:If your variables are all volatile then accessing and modifying those values is thread safe only you are performing single atomic actions (getting the value or setting the value). If you need to perform multiple accesses or repeated access then just using volatile variables is not enough to prevent inconsistent data.
One consequence of this that people sometimes don't realize is that operations like i++ are not made thread-safe just by making the variable volatile, because they are not atomic--there's a read and a write there, so, for example, two threads can read the same value, increment it, and write the same value, and the variable gets incremented by one when it should have been by two.
A class can be made thread-safe even without the volatile or synchronized keywords. Properly designed immutable class (such as String) is always thread-safe, even though it doesn't use any synchronization at all. Not sure whether this is what the interviewer wanted to hear, but nevertheless, using immutable classes can make multithreaded application significantly simpler.
Synchronized and volatile "can" cause a memory barrier, this is important as some programmers jump on these as expensive insisting they always do , they will establish "happens before order" if that requires a memory barrier then it can be presumed to happen. See lock elision etc , coarsening etc etc . there are some gotchas for using synchronized as a memory barrier e.g. local variables.
By immutable you mean strictly "thread immutable" which it is very important distinction e.g. the early problems with String where it mutated its internal state but appeared immutable .. no setters and even with strings you still have to get hold of the initial reference etc i.e. not see null.
The long answer is yes to the question the simplest answer is no, you could make the program single threaded ;-) , you could use the new concurrency API's, memory fence API etc etc .. in an interview the answer yes/no shouldn't matter more that you understand the issues.
"Eagles may soar but weasels don't get sucked into jet engines" SCJP 1.6, SCWCD 1.4, SCJD 1.5,SCBCD 5
Chris Hurst wrote: e.g. the early problems with String where it mutated its internal state but appeared immutable...
I tried to search for these early problems with String, but to no avail. Could you provide a link? (I'm a curious person....)
Well, String was probably not a good choice to illustrate my point, since it indeed has a mutable internal state (the hash code), which is not exposed to the outside world (and therefore is still thread safe). However, the simplest case on an immutable class - a class with all member variables declared final - is always thread-safe, by definition. It is guaranteed by the JLS.
That a reference to an immutable class could be used in a thread-unsafe way is completely different (but nevertheless valid) point.
My issue is I have a lot of code presented to me with we don't need synchronization because it's immutable but it doesn't pass the thread immutable tests. I realised you know the difference but for the casual reader it possibly needs spelling out.
Joined: Aug 03, 2006
Thanks a lot everyone for the replies.. Its much clear now.