制作DateFormat Threadsafe.使用什么,同步或线程本地

Ahm*_*ood 8 java multithreading thread-safety

我想让以下代码线程安全.实现它的最佳方法是什么?

private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance();

public static final String eventTypeToDateTimeString(long timestamp)
{
   return DATE_FORMAT.format(new Date(timestamp));
}
Run Code Online (Sandbox Code Playgroud)

Bas*_*que 10

避免遗留日期时间类

与最早版本的Java捆绑在一起的麻烦的旧日期时间类已被java.time类所取代.java.time类是线程安全的并且使用不可变对象.

java.time

用java.time类型替换格式化程序和日期类型以自动获得线程安全性.

DateTimeFormatter如果需要,定义全局.该类可以自动本地化生成的字符串,也可以指定某种格式.

  • 指定a FormatStyle以确定缩写的长度.
  • 指定a Locale以确定(a)用于翻译日期名称,月份名称等的人类语言,以及(b)决定缩写,大小写,标点符号等问题的文化规范.
  • 指定ZoneId用于调整时刻的时区.

该Instant级表示时间轴上的时刻UTC,分辨率为纳秒.该ZonedDateTime级的调整Instant到特定的时区.

您的代码,转换为java.time类.在实际工作中,我会将其分解为多行,并将陷入异常.

private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ;
private static final ZoneId ZONE_ID = ZoneId.of( "America/Montreal" );

public static final String eventTypeToDateTimeString(long timestamp)
{
   return Instant.ofEpochMilli( timestamp ).atZone( ZONE_ID ).format( DATE_TIME_FORMATTER );
}
Run Code Online (Sandbox Code Playgroud)

不要将日期时间跟踪为从纪元开始计算

我不建议绕过一个long表示日期时间值的方法.由于人类无法辨别日期时间值的含义,因此调试和记录难度很大.相反,传递java.time类型,如Instant.使用java.time类型可提供类型安全性,并使您的代码更加自我记录.


关于java.time

该java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

现在处于维护模式的Joda-Time项目建议迁移到java.time类.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*

从哪里获取java.time类?

该ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.