SimpleDateFormat的javadoc声明SimpleDateFormat未同步.
"日期格式不同步.建议为每个线程创建单独的格式实例.如果多个线程同时访问格式,则必须在外部同步."
但是在多线程环境中使用SimpleDateFormat实例的最佳方法是什么.以下是我想到的一些选项,我过去使用过选项1和2,但我很想知道是否有更好的替代方案或哪些选项可以提供最佳性能和并发性.
选项1:在需要时创建本地实例
public String formatDate(Date d) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(d);
}
Run Code Online (Sandbox Code Playgroud)
选项2:将SimpleDateFormat的实例创建为类变量,但同步对其的访问.
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public String formatDate(Date d) {
synchronized(sdf) {
return sdf.format(d);
}
}
Run Code Online (Sandbox Code Playgroud)
选项3:创建ThreadLocal以为每个线程存储SimpleDateFormat的不同实例.
private ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>();
public String formatDate(Date d) {
SimpleDateFormat sdf = tl.get();
if(sdf == null) {
sdf = new SimpleDateFormat("yyyy-MM-hh");
tl.set(sdf);
}
return sdf.format(d);
}
Run Code Online (Sandbox Code Playgroud) 我对ThreadLocal的有限理解是它存在资源泄漏问题.我收集这个问题可以通过在ThreadLocal中正确使用WeakReferences来解决(尽管我可能误解了这一点.)我只是想要一个模式或示例来正确使用带有WeakReference的ThreadLocal(如果存在).例如,在此代码片段中,将引入WeakReference?
static class DateTimeFormatter {
private static final ThreadLocal<SimpleDateFormat> DATE_PARSER_THREAD_LOCAL = new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy/MM/dd HH:mmz");
}
};
public String format(final Date date) {
return DATE_PARSER_THREAD_LOCAL.get().format(date);
}
public Date parse(final String date) throws ParseException
{
return DATE_PARSER_THREAD_LOCAL.get().parse(date);
}
}
Run Code Online (Sandbox Code Playgroud)