콘텐츠로 건너뛰기

SimpleDateFormat은 Multi-thread 환경에서 쓸 수 없다.

java.lang.ArrayIndexOutOfBoundsException: 13
at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(BaseCalendar.java:454) ~[na:1.7.0_45]
at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2333) ~[na:1.7.0_45]
at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2248) ~[na:1.7.0_45]
at java.util.Calendar.setTimeInMillis(Calendar.java:1140) ~[na:1.7.0_45]
at java.util.Calendar.setTime(Calendar.java:1106) ~[na:1.7.0_45]
at java.text.SimpleDateFormat.format(SimpleDateFormat.java:955) ~[na:1.7.0_45]
at java.text.SimpleDateFormat.format(SimpleDateFormat.java:948) ~[na:1.7.0_45]
at java.text.DateFormat.format(DateFormat.java:296) ~[na:1.7.0_45]

위처럼 에러가 나고, 확인했더니 SimpleDateFormat은 thread-safe 하지 않다고 한다.
멀티 스레드 환경에서 값의 변조에 관련된 부분이야 당연히 문제가 될 거라는 생각은 했는데,
해당 객체에 대한 access-lock이 풀리지 않으면, 다른 객체는 접근할 수 없다는 사실은 몰랐다.

결국 해결책은
1) 각 thread에서 각각 SimpleDateFormat는 new 생성해서 사용하는 방법
2) thread local을 이용해서 생성해서 쓰는 방법
3) synchronized해서 wait하는 방법
4) commons lang에서 제공하는 FastDateFormat을 사용하는 방법
이 있다.

성능표를 보면 당연히 thread local을 사용하는 게 가장 tps 좋게 나왔는데,
사실 댓글에 나온(4번 해결책)이 가장 나을 것 같다.

참조 : 
http://www.javacodegeeks.com/2010/07/java-best-practices-dateformat-in.html

http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/FastDateFormat.html

 

태그:

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다