转发自:http://blog.jrwang.me/2016/java-simpledateformat-multithread-threadlocal/
如何保证 SimpleDateFormat 的线程安全
最简单的方法就是每次要使用 SimpleDateFormat 时都创建一个局部的 SimpleDateFormat 对象。局部变量,自然就不存在线程安全的问题了。但如果需要频繁进行调用的话,每次都要创建新的对象,开销太大。
第二种方式,就是对 SimpleDateFormat 进行加锁,这样可以确保同一时间只有一个线程可以持有锁,进而解决线程安全的问题。但是这种方法在多线程竞争激烈的时候会带来效率问题。
第三种方式,就是使用 ThreadLocal。 ThreadLocal 可以确保每个线程都可以得到单独的一个 SimpleDateFormat 的对象,那么自然也就不存在竞争问题了。
public class DateUtil {
private static ThreadLocal<SimpleDateFormat> local = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
public static String format(Date date) {
return local.get().format(date);
}
public static Date parse(String dateStr) throws ParseException {
return local.get().parse(dateStr);
}
}
用 ThreadLocal 来实现其实是有点类似于缓存的思路,每个线程都有一个独享的对象,避免了频繁创建对象,也避免了多线程的竞争。
也可以将 SimpleDateFormat 对象的创建进行延迟加载:
public class DateUtil {
private static ThreadLocal<SimpleDateFormat> local = new ThreadLocal<SimpleDateFormat>();
private static SimpleDateFormat getDateFormat() {
SimpleDateFormat dateFormat = local.get();
if (dateFormat == null) {
dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
local.set(dateFormat);
}
return dateFormat;
}
public static String format(Date date) {
return getDateFormat().format(date);
}
public static Date parse(String dateStr) throws ParseException {
return getDateFormat().parse(dateStr);
}
}
本文介绍了如何使用ThreadLocal确保SimpleDateFormat在多线程环境下的线程安全问题,提供了三种实现方式,并详细解释了使用ThreadLocal的优劣。
1074

被折叠的 条评论
为什么被折叠?



