SimpleDateFormat在并发环境下不是线程安全. jdk文档有注释.
* 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
*
* @see <a href="https://docs.oracle.com/javase/tutorial/i18n/format/simpleDateFormat.html">Java Tutorial</a>
* @see java.util.Calendar
* @see java.util.TimeZone
* @see DateFormat
* @see DateFormatSymbols
* @author Mark Davis, Chen-Lieh Huang, Alan Liu
threadLocal可以解决此问题,每个线程单独创建一个SimpleDateFormat,各个线程互不影响.代码如下
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
public class DateUtil {
private static final ThreadLocal<Map<String,SimpleDateFormat>> dateFormatThreadLocal = new ThreadLocal<Map<String, SimpleDateFormat>>(){
@Override
protected Map<String, SimpleDateFormat> initialValue() {
return new HashMap<String, SimpleDateFormat>();
}
};
private static SimpleDateFormat getSimpleDateFormat(String datePattern){
dateFormatThreadLocal.get().putIfAbsent(datePattern, new SimpleDateFormat(datePattern));
return dateFormatThreadLocal.get().get(datePattern);
}
public static void main(String [] args){
new Thread(new Runnable() {
@Override
public void run() {
for(int i=1;i<=1;i++){
SimpleDateFormat simpleDateFormat = DateUtil.getSimpleDateFormat("yyyy-MM-dd");
System.out.println(Thread.currentThread().getName()+"-------"+simpleDateFormat);
}
}
},"thread1").start();
new Thread(new Runnable() {
@Override
public void run() {
for(int i=1;i<=2;i++){
SimpleDateFormat simpleDateFormat = DateUtil.getSimpleDateFormat("yyyy-MM-dd");
System.out.println(Thread.currentThread().getName()+"-------"+simpleDateFormat);
}
}
},"thread2").start();
}
}
网友评论