SimpleDateFormat은 JDK 전 벤더사에 걸쳐서 Thread Safe하지 않으며 객체생성시(new SimpleDateFormat) 많은 연산으로 CPU를 잡아먹는다.

Java Doc 내용:

Synchronization      
    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.

그래서 SimpleDateFormat을 여러 Thread에서 사용시에 엉뚱한 날짜가 계산되어 나오는 경우가 있다.
실제 문제가 발생하여 테스트시 format() 메소드만 타면 간혹 엉뚱한 값이 나왔다.
물론 매번 new SimpleDateFormat을 하면 괜찮지만 CPU를 상당히 많이 잡아 먹기 때문에 좋지 않다.



이에 대한 여러가지 해결방법이 제안되었는데

1. syncronized를 사용하여 Thread Safety를 보장 하는 방법
    http://www.codefutures.com/weblog/andygrove/2007/10/simpledateformat-and-thread-safety.html

2. Thread Local 변수를 사용하는 방법
    http://www.thedwick.com/blog/?p=131

3. instance를 Map에 넣어 Sharing 하는 방법
    http://li-ma.blogspot.com/2007/10/thread-safe-date-formatparser.html

이 있다.

개인적으로 테스트 해보기론 1, 2번을 사용할 경우 어느 정도 성능이 약간 떨어지긴하지만 정상적인 결과를 가져온다. 3번의 경우 속도가 빠르며 어느정도의 부하상황(여러 Thread들이 사용하는 경우)을 견디긴 하지만 많은 Thread에서 생성하여 테스트할 경우 엉뚱한 값이 나옴을 볼 수 있었다. 어느 정도의 방어로직은 되지만 100% 보장되는 방법은 아니다.

결국 결론은 apache의 FastDateFormat으로 가는 것 같다.
가능한 방법을 모두 정리해둔 주소를 googling으로 찾을 수 있었다. (http://solidsimplesafe.com/view/13)
위 주소의 마지막 내용을 보면 속도 및 안정성에 대해 간략한 표가 정리되어있다.
발췌 :
 Style  speed ranking
 notes
 FastDateFormat  1  safe and fast
 DateFormat - shared instance
 2  unreliable, don't use
 Joda  3  likely to be in java 7, the way
 DateFormat with synchronization
 4  works, but brittle, could be easily broken by unwitting programmers
 DateFromat with ne
 5   works, but brittle, could be easily broken by unwitting programmers


Apache의 FastDateFormat(commons-lang-2.4.jar) 를 보면 format() 메소드만 지원되고 parse()는 지원하지 않는다.
또한 new FastDateFormat을 사용하지 않고 FastDateFormat.getInstance()를 사용하면 Map을 통해 instance를 sharing 한다.
실제 FastDateFormat 소스를 보면 상당히 간결하며 commons-lang-2.4.jar에 있는 Validate Class(?)와 FastDateFormat Class만 있으도 된다.






다음은 SimpleDateFormat을 사용한 경우와 FastDateFormat을 사용한 경우에 대해 테스트한 샘플이다.
소스가 왜이리 더럽냐고 한다면 그저 마주볼뿐..

SimpleDateFormat을 사용하는 경우 샘플 소스 : 엉뚱한 값이 나올 경우 콘솔에 print 한다.


FastDateFormat을 사용하는 경우 샘플 소스 : 정상동작하므로 콘솔에 print되는 정보가 없다.




이상 끝.




'Java' 카테고리의 다른 글

Java Thread  (0) 2010.01.24
Exception 을 문자열로...  (0) 2009.09.07
Java Compile 사용  (0) 2009.08.26
Java에서 외부 프로그램 실행  (0) 2009.08.26
용어 설명  (0) 2009.02.23
jconsole test - (sun jdk 1.5)  (0) 2009.02.23
SUN JDK 1.4.2 Heap dump Option  (0) 2009.01.30
JVM 기타  (0) 2009.01.30