【发布时间】:2013-06-06 18:12:28
【问题描述】:
我有一个包含许多表的数据库,这些表以 UTC 数字格式(修改后的儒略日数字)存储日期/时间。
这很好用,但当然需要向用户显示任何时间日期,日期/时间必须从 UTC 数字格式转换为本地化字符串格式。因为 JDK 日历 API 提供了历史上准确的夏令时和时区偏移,所以我一直使用公历来实现这个唯一目的。我只使用它来将时间戳从 UTC 映射到本地时间。
因为我有很多表需要执行这种转换,而且创建日历对象的成本很高,所以我只在语言环境时区更改时才创建新的 GregorianCalendar 对象。我一直将当前日历保存在 JulianDay 类的静态成员字段中(该类提供了我用来提供 UTC 到本地映射的函数)。以下是 JulianDay 的字段:
public final class JulianDay {
private static final int YEAR = 0;
private static final int MONTH = 1;
private static final int DAY = 2;
private static final int HOURS = 3;
private static final int MINUTES = 4;
private static final int SECONDS = 5;
private static final int MILLIS = 6;
public static final double POSIX_EPOCH_MJD = 40587.0;
private static final String TIME_ZONE_UTC = "UTC";
private static final GregorianCalendar CAL_UTC =
new GregorianCalendar(TimeZone.getTimeZone(TIME_ZONE_UTC));
private static GregorianCalendar c_selCal = null;
public static void setCurrentCalendar(String tzid)
{ JulianDay.c_selCal = JulianDay.findCalendarForTimeZone(tzid); }
public static GregorianCalendar getCurrentCalendar()
{ return JulianDay.c_selCal; }
:
:
}
以上是在单线程客户端 GUI 应用程序中,但我很快需要开发一个服务器端 Web 应用程序,它将使用该 API 的大部分内容。我需要弄清楚如何保留我对 JDK 日历 API 的投资,并以某种方式保证我的应用程序线程安全。 Joda time 是一个选项,但如果可能的话,我不想添加该依赖项(无论如何,我使用 Java API 只是简单模式访问时区数据库)。
由于日历显然是线程敌对的,我不确定如何从这里开始。
我的想法是,由于 JulianDay 类构造了 GregorianCalendar 的所有实例(来自时区 id 字符串),我可以重构我的代码,这样我就可以消除发布日历引用的 getCurrentCalendar() 方法。
如果我可以将所有对GregorianCalendar 的访问限制在JulianDay 内,我是否可以安全地假设,即使它是一个危险的可变类,我的应用程序也是线程安全的?即使在我的JulianDay 类中,我仍然需要将对GregorianCalendar 的访问与锁定对象同步,对吗?
【问题讨论】:
-
也许使用
ThreadLocal<Calendar>?
标签: java calendar thread-safety