SimpleDateFormat을 static 변수로 잡아서 사용한다면 Thread Safety에 유의해야만 한다.
SimpleDateFormat은 Javadoc에 따르면 thread-safe하지 않다.
따라서 사용자가 Thread Safety를 보장해주거나,
thread-safe한 DateFormat 클래스를 사용해야만 한다.
다음은 SimpleDateFormat 클래스가 thread-safe하지 않음을 보여주는 예제이다.
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 객체를 갖도록 하는 것이다.
댓글 없음:
댓글 쓰기