同步对SimpleDateFormat的访问

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)

Pet*_*ego 42

  1. 创建SimpleDateFormat很昂贵.除非很少这样做,否则不要使用它.

  2. 好的,如果你能忍受一点阻塞.如果formatDate()使用不多,请使用.

  3. 最快的选项如果您重用线程(线程池).使用的内存多于2,并且启动开销较高.

对于应用程序,2和3都是可行的选择.哪种情况最适合您的情况取决于您的使用案例.注意过早优化.只有在你认为这是一个问题时才这样做.

对于第三方使用的图书馆,我会使用选项3.


Ada*_*ent 24

另一个选项是Commons Lang FastDateFormat,但您只能将其用于日期格式化而不能解析.

与Joda不同,它可以作为格式化的替代品.(更新:自v3.3.2起,FastDateFormat可以生成FastDateParser,它是SimpleDateFormat的插入式线程安全替代品)

  • 从Commons Lang 3.2开始,`FastDateFormat`也有`parse()`方法 (8认同)

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相同的格式/解析模式规范.


Jed*_*ith 5

不要使用 SimpleDateFormat,而是使用 joda-time 的 DateTimeFormatter。它在解析方面有点严格,因此并不能完全替代 SimpleDateFormat,但 joda-time 在安全性和性能方面对并发更加友好。