SimpleDateFormat 的文档中其实已经指明了这种情况。
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.
示例代码:
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
public class SimpleDateFormatMultithread {
private static final SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
public static void bench() throws Exception {
Callable<Date> task = new Callable<Date>() {
public Date call() throws Exception {
return fmt.parse("20101022");
}
};
// pool with 5 threads ExecutorService exec = Executors.newFixedThreadPool(5);
List<Future<Date>> results = new ArrayList<Future<Date>>();
// perform 10 date conversions for (int i = 0; i < 10; i++) {
results.add(exec.submit(task));
}
exec.shutdown();
// look at the results for (Future<Date> result : results) {
System.out.println(result.get());
}
}
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
bench();
}
}
}
多运行几次会出现以下几种问题:
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NumberFormatException: For input string: ""
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NumberFormatException: multiple points
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NumberFormatException: For input string: "E120"
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
处理方法:
- 局部化
- 使用ThreadLocal
参考:
“Java DateFormat is not threadsafe” what does this leads to?