Pages

2014년 12월 4일 목요일

[JAVA] SIMPLE DATE FORMAT AND Thread Safe

SimpleDateFormat을 static 변수로 잡아서 사용한다면 Thread Safety에 유의해야만 한다.

SimpleDateFormat은 Javadoc에 따르면 thread-safe하지 않다.

따라서 사용자가 Thread Safety를 보장해주거나,

thread-safe한 DateFormat 클래스를 사용해야만 한다.

다음은 SimpleDateFormat 클래스가 thread-safe하지 않음을 보여주는 예제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
 
public class ProveNotSafe {
    static SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy", Locale.ENGLISH);
    static String testdata[] = { "01-Jan-1999", "14-Feb-2001", "31-Dec-2007" };
 
    public static void main(String[] args) {
        Runnable r[] = new Runnable[testdata.length];
        for (int i = 0; i < r.length; i++) {
            final int i2 = i;
            r[i] = new Runnable() {
                public void run() {
                    try {
                        for (int j = 0; j < 1000; j++) {
                            String str = testdata[i2];
                            String str2 = null; /*synchronized(df)*/ 
                            {
                                Date d = df.parse(str);
                                str2 = df.format(d);
                            }
                            if (!str.equals(str2)) {
                                throw new RuntimeException("date conversion failed after " + j + " iterations. Expected " + str + " but got " + str2);
                            }
                        }
                    } catch (ParseException e) {
                        throw new RuntimeException("parse failed");
                    }
                }
            };
            new Thread(r[i]).start();
        }
    }
}
 

실행 결과는 다음과 같다.

Exception in thread "Thread-2" java.lang.RuntimeException: date conversion failed after 0 iterations. Expected 31-Dec-2007 but got 14-Dec-2007
 at ProveNotSafe$1.run(ProveNotSafe.java:26)
 at java.lang.Thread.run(Thread.java:619)
Exception in thread "Thread-1" java.lang.RuntimeException: date conversion failed after 0 iterations. Expected 14-Feb-2001 but got 14-Feb-20100
 at ProveNotSafe$1.run(ProveNotSafe.java:26)
 at java.lang.Thread.run(Thread.java:619)
Exception in thread "Thread-0" java.lang.RuntimeException: date conversion failed after 0 iterations. Expected 01-Jan-1999 but got 14-Feb-20100
 at ProveNotSafe$1.run(ProveNotSafe.java:26)
 at java.lang.Thread.run(Thread.java:619)


주석 처리된 synchronized (df)를 활성화시키면 문제는 해결된다.

동기화 방식은 불필요한 병목이 될 수 있으므로 이상적으로는 쓰레드마다 자신의 

SimpleDateFormat 객체를 갖도록 하는 것이다.

댓글 없음:

댓글 쓰기