5

The question regards Java's SimpleDateFormat class. I've read in the documentation that

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.

Obviously, I've read that after being hit in the most obscure way by it.

Does anybody know why would it be necessary to have state information in class members accessed by the "format" method for example?

Is it a speed optimization of some sort? I couldn't come up with a valid reason.

Tudor Vintilescu
  • 1,450
  • 2
  • 16
  • 28
  • 1
    That's just its definition. It's been that way for some time. Maybe the better question is why haven't they fixed it? – Gray Sep 27 '12 at 18:11
  • 1
    It was probably just a design choice. I've been working with code like that lately, that stores temporary state in member variables, and it's very difficult to debug/refactor. I wouldn't recommend it, and I'd even go so far to say it's not very good practice. – Brian Sep 27 '12 at 18:11
  • Maybe it uses a kind of flyweight pattern in order to save some memory. – Mik378 Sep 27 '12 at 18:12
  • 1
    Not good practice is saying it mildly @Brian. It's terrible practice. – Gray Sep 27 '12 at 18:12
  • I disagree that it is a terrible practice. People writing very general code, like date handling, have no idea whether the caller will need the extra code and execution time synchronization takes. Date stuff can get very intricate and tedious internally, and I would rather not have my time-critical single-threaded use of it slowed down by checking on monitors that that application has no use for. That IS its definition, and you didn't realize it ahead of time. If you're writing multi-threaded code, you're going to need to seek out the concurrency issues with anything you use. – arcy Sep 27 '12 at 18:17
  • 3
    It's just ooooooooooooooooooold. We tend to forget Java 1 was drafted 20+ years ago :) Garbage Collection was super slow, Object Creation was super expensive, reusing a single Calendar instance was a significant optimization in a time when 'multi-threading' was something graduate students played with and nobody but the crack team at SGI attempted for "real" software. – Affe Sep 27 '12 at 18:23
  • possible duplicate of [SimpleDateFormat thread safety](http://stackoverflow.com/questions/6840803/simpledateformat-thread-safety) – seh Sep 27 '12 at 18:53

2 Answers2

8

Your answer pretty much lies here:

/* * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved

Prior to 1.4 hotspot writing multi-threaded code in Java was primarily a homework assignment for graduate students. The language had been around 10 years before the serious arrival of web-application servers and rise of the container-driven highly concurrent systems that most of us (non-android anyway) spend the vast majority of our time working in.

In 1996, Garbage Collection was a very slow and painful process that generally made your UI pause and look locked up while it happened, like wise creating new objects was considered very expensive (creating contiguous memory space when you're fighting with Windows 95 for a share of 4MB of physical memory with no L2 CPU cache takes some time.....).

So in an environment where multi-threading is extremely rare, and memory is at a premium (your average user is probably still on a 486 or Pentium 1 with 8MB or even 4MB of system memory....) it makes perfect sense to re-use a single instance of Calendar as much as possible, Calendar itself being something of a clunky beast.

We can scoff today at what a horrible practice it is for a class like that to be stateful, but it can also be easily defended as the right choice at the time.

Defending Sun's obsession with 100% backward compatibility and never updating it is another matter of course!

Affe
  • 47,174
  • 11
  • 83
  • 83
  • 1
    date formatting is so complex and expensive, the overhead of 1 object should be negligible. the real constraint was probably from Calendar API that makes it impossible to design a thread safe and fast formatter. the Calendar API is apparently badly designed and widely hated. – irreputable Sep 27 '12 at 19:11
  • That's comparing CPU time to Memory usage. When memory is constrained, wasted memory is wasted memory. On non-pipelined/primitively pipelined processors, you can do an awful lot of calculating in the time it takes to deal with the memory bus. Also the performance cost of the wasted memory in GC pauses is at an unpredictable time, not a slower response to the specific user operation. I have no data and no way to generate any, but it would not surprise me at all if on a common 1996 jvm+desktop computer the Calendar object allocation+gc actually is comparable to the calculation cost. – Affe Sep 27 '12 at 19:51
  • The calculation requires HUGE amount of memory reads/writes, lots of method invocations. A primitive VM couldn't optimize them either. You are giving the authors too much benefit of doubt; it's most likely just an API design fail. – irreputable Sep 27 '12 at 21:09
  • I suspect the fundamental reason for the lack of thread-safety is that Java has no mechanism via which a called function can return multiple values without creating a new heap object to hold them or abusing an existing object for that purpose. – supercat Mar 17 '14 at 23:18
1

It looks like it is done for the performance reason. I see no other explanations for it.

There is a good summary on how it works here: Why is Java's SimpleDateFormat not thread-safe?

Community
  • 1
  • 1
  • It could be thread safe and fast. The performance reason must be rooted in some engineering or even political reasons. – irreputable Sep 27 '12 at 19:01