Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion about thread safety - SimpleDateFormat example

I have a question about thread safety. From what I have been told, SimpleDateFormat is not thread safe. I was wondering what effects it would have if I use it the following way in my spring controller:

private final static SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd yyyy", Locale.US);

Later in my of my controller functions I use it as follows:

  try {
        changedate = changedate.substring(0, 15);                                                
        calcDate = dateFormat.parse(changedate);
    } catch (ParseException e2) {
        logger.error("Date Parsing Problem", e2); 
    }

calcDate then gets added to my model object and a ModelAndView is returned.

So what kind of problems will I see using it this way? Would simply removing the static keyword fix any issues because then each thread will use its own instance of dateFormat? Any clarity on this subejct in regards to thread safety would be much appreciated.

Thanks

like image 944
blong824 Avatar asked Apr 13 '11 16:04

blong824


People also ask

Why is SimpleDateFormat not thread-safe?

The SimpleDateFormat class mutates its internal state for formatting and parsing dates. That's why it results in these issues when multiple threads use the same instance of SimpleDateFormat concurrently.

Is SimpleDateFormat can be used in multithreaded environment?

If multiple threads access a format concurrently, it must be synchronized externally . To make the SimpleDateFormat class thread-safe, look at the following approaches : Create a new SimpleDateFormat instance each time you need to use one. Although this is thread safe, it is the slowest possible approach.

Is SimpleDateFormat safe?

2.2. Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally. So SimpleDateFormat instances are not thread-safe, and we should use them carefully in concurrent environments.

What can I use instead of SimpleDateFormat?

DateTimeFormatter is a replacement for the old SimpleDateFormat that is thread-safe and provides additional functionality.


4 Answers

SimpleDateFormat.parse() uses an instance variable called calendar to build the date from the string. If two threads try to parse at the same time, the calendar variable will get clobbered and you'll get wrong results.

Making the variable not static won't necessarily help, since two threads could still be using the same controller. A better solution is to either create a new DateFormat object each time you parse a date, or use thread local storage. Better still, use JodaTime which has thread safe parsers.

like image 188
ataylor Avatar answered Oct 16 '22 06:10

ataylor


So what kind of problems will I see using it this way?

Developers of SimpleDateFormat took a very strange decision - during work of parse() they store partially parsed date in a field of SimpleDateFormat. Obviously, it means that you can't call parse() from several threads simultaneously.

Would simply removing the static keyword fix any issues because then each thread will use its own instance of dateFormat?

Removing static won't help you, since Spring controllers are singleton scoped by default, so Spring uses a single instance of your controller to serve all requests.

like image 38
axtavt Avatar answered Oct 16 '22 05:10

axtavt


Personally, I would avoid all these issues by just using JodaTime. The API is much richer, it doesn't have the threading issues, and it's a lot faster.

like image 37
dty Avatar answered Oct 16 '22 06:10

dty


SimpleDateFormat has instance-wide state while parsing and is therefore not thread safe. If you use it from multiple threads it will crash (well like java crashes :-), no process crash and the like). Removing static keyword doesn't necessarily cure the problem because it depends on the instance and it still might be used from several threads.

You can create a local instance within the method above so that each parsing happens with its own formatter or play with threadlocal variables.

like image 34
Tomasz Stanczak Avatar answered Oct 16 '22 06:10

Tomasz Stanczak