3ur*_*och 86 java concurrency multithreading simpledateformat
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)
Ada*_*ent 24
另一个选项是Commons Lang FastDateFormat,但您只能将其用于日期格式化而不能解析.
与Joda不同,它可以作为格式化的替代品.(更新:自v3.3.2起,FastDateFormat可以生成FastDateParser,它是SimpleDateFormat的插入式线程安全替代品)
Pau*_*gas 16
如果您使用的是Java 8,则可能需要使用java.time.format.DateTimeFormatter:
这个类是不可变的和线程安全的.
例如:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String str = new java.util.Date().toInstant()
.atZone(ZoneId.systemDefault())
.format(formatter);
Run Code Online (Sandbox Code Playgroud)
小智 6
Commons Lang 3.x现在有FastDateParser和FastDateFormat.它比SimpleDateFormat更安全,更快.它还使用与SimpleDateFormat相同的格式/解析模式规范.
不要使用 SimpleDateFormat,而是使用 joda-time 的 DateTimeFormatter。它在解析方面有点严格,因此并不能完全替代 SimpleDateFormat,但 joda-time 在安全性和性能方面对并发更加友好。