同步对SimpleDateFormat的访问

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (44)

SimpleDateFormat的javadoc声明SimpleDateFormat不同步。

“日期格式不同步,建议为每个线程创建单独的格式实例,如果多个线程同时访问一个格式,它必须在外部同步。”

但在多线程环境中使用SimpleDateFormat实例的最佳方法是什么?以下是我想到的一些选项,过去我使用过选项1和2,但我很想知道是否有更好的选择,或者哪些选项可以提供最佳性能和并发性。

选项1:在需要时创建本地实例

public String formatDate(Date d) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    return sdf.format(d);
}

选项2:创建一个SimpleDateFormat实例作为类变量,但同步对它的访问。

private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public String formatDate(Date d) {
    synchronized(sdf) {
        return sdf.format(d);
    }
}

选项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);
}
提问于
用户回答回答于
  1. 创建SimpleDateFormat非常昂贵。除非很少做,否则不要使用它。
  2. 好的,如果你能忍受一点阻塞。如果formatDate()用处不大,则使用。
  3. 如果你重用线程(线程池),最快的选择。使用比2更多的内存,并具有更高的启动开销。

对于应用程序2.和3.都是可行的选项。哪个最适合你的情况取决于你的用例。谨防过早优化。只有在你认为这是一个问题时才会这样做。

对于第三方会使用的库,我会使用选项3。

用户回答回答于

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

与Joda不同,它可以作为格式化的直接替代品。(更新:从v3.3.2开始,FastDateFormat可以生成一个FastDateParser,它是SimpleDateFormat的一个嵌入式线程安全替代品)

所属标签

可能回答问题的人

  • 嗨喽你好

    7 粉丝480 提问8 回答
  • uncle_light

    5 粉丝518 提问7 回答
  • 富有想象力的人

    3 粉丝0 提问6 回答
  • 人生的旅途

    10 粉丝484 提问6 回答

扫码关注云+社区

领取腾讯云代金券