Lets take SimpleDateFormat as an example since it is not thread safe.
I could allow each thread to have its own copy of SimpleDateFormat using threadLocal like this:
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
But the volatile keyword guarantees that a thread will have the most recent copy of the variable. So could i not do this instead:
volatile SimpleDateFormat myformatter;
and achieve the same thread safety ?
the volatile keyword guarantees that a thread will have the most recent copy of the variable
Of the volatile variable only, not its fields.
Also, volatile
is only useful if you need to change the value of the variable. In your use case, final
looks like it would be more appropriate:
private static final SimpleDateFormat format = ...
This also guarantees that you will have the most recent value of the variable - because it can only be assigned its value once, and static final
has guarantees the visibility once the class is fully loaded.
But this isn't the reason why SimpleDateFormat
is not thread safe anyway: it has mutable state which it uses to store intermediate values when formatting the date.
If one thread calls format
while another is also in the format
method for the same SimpleDateFormatter
instance, these intermediate variables get stomped unpredictably, leading to interference between the threads, and hence unpredictable output.
It doesn't matter whether or not the values of these intermediate variables are up-to-date when read/written by another thread - their updating can be interspersed.
In short, volatile
doesn't prevent thread interference, and so is not an appropriate alternative to a ThreadLocal
here.