The methods parse() and format() in java.text.Format contain a design flaw that can cause one user to see another user's data.
The methods parse() and format() in java.text.Format contains a race condition that can cause one user to see another user's data.
Example 1: The code below shows how this design flaw can manifest itself.
While this code will behave correctly in a single-user environment, if two threads run it at the same time they could produce the following output:
Time in thread 1 should be 12/31/69 4:00 PM, found: 12/31/69 4:00 PM
Time in thread 2 should be around 12/29/09 6:26 AM, found: 12/29/09 6:30 AM
In this case, the date from the first thread is shown in the output from the second thread due a race condition in the implementation of format().
So format() is not threadsafe. I am using format() in many places in servlet. Instead of synchroized the methos or using synch block, can I make the variable local so that it will thread safe. Please advice that approach will address the above issue.
Instead of gloabl var (private static SimpleDateFormat dateFormat;), making dateFormat as local var will solve the issue for above case
Yes, making the object local will avoid thread safety issues.
This is not a design flaw, though, it's a design decision - the javadocs specifically mention that the class is not thread-safe (as they do for many other classes). So it's clear that the developer needs to provide that.
The reason why it's not thread-safe is because synchronization has runtime overhead (it makes the program run a little bit slower) and most of the time you don't need thread safety with for example a SimpleDateFormat object, because you're most of the time not using the same SimpleDateFormat object from multiple threads at the same time.
One way to avoid thread safety issues is by making the SimpleDateFormat a local variable; another way is by using thread-local storage. When you do this, a separate SimpleDateFormat object will be created for every thread that uses it. You do that like this:
So you wrap the DateFormat object in a ThreadLocal. Note that you have to call get() on the ThreadLocal (see line 14) to get the actual DateFormat object.