我在一个被定义为"线程安全"的类中有两个共享的可变对象。
public static final GregorianCalendar CAL = new GregorianCalendar();
public static final SimpleDateFormat SDF = new SimpleDateFormat();
旨在减少对象创建的数量,因为这些对象的创建成本较高,并且预计需要频繁调用使用它们的方法。
以下是其中一个(静态工厂)方法:
public static MJD ofTimeStampInZone(String stamp, String form, TimeZone tz) {
double result;
synchronized(lockCal) {
synchronized(lockSdf) {
CAL.setTimeZone(tz);
SDF.setCalendar(CAL);
SDF.applyPattern(form);
try {
Date d = SDF.parse(stamp);
CAL.setTime(d);
result = (CAL.getTimeInMillis() / (86400.0 * 1000.0)) +
POSIX_EPOCH_AS_MJD;
}
catch (ParseException e)
{ throw new IllegalArgumentException("Invalid parsing format"); }
}
}
return new MJD(result);
}
我也为这个类设置了一个规则,即必须在
lockSdf
之前获取lockCal
。然而,对于这个类来说,以下情况也是正确的:
- 可以锁定并使用CAL而不使用SDF,在这种情况下,SDF没有被锁定。
- SDF在方法中从未被使用,除非也使用了CAL。
lockCal
上加锁是否足以防止并发访问期间的数据不一致。这将使我不需要对SDF进行锁定。换句话说,如果只使用以下内容,是否仍保证线程安全性: public static MJD ofTimeStampInZone(String stamp, String form, TimeZone tz) {
double result;
synchronized(lockCal) {
CAL.setTimeZone(tz);
SDF.setCalendar(CAL);
SDF.applyPattern(form);
try {
Date d = SDF.parse(stamp);
CAL.setTime(d);
result = (CAL.getTimeInMillis() / (86400.0 * 1000.0)) +
POSIX_EPOCH_AS_MJD;
}
catch (ParseException e)
{ throw new IllegalArgumentException("Invalid parsing format"); }
}
return new MJD(result);
}
lockCal
和lockSdf
上的代码? - Tim BiegeleisenlockCal
和lockSdf
。我还有几种只锁定lockCal
的方法,但这些方法不会改变SDF
的状态。 - scottbofTimeStampInZone
展示的内容即可。 - Tim Biegeleisen