gpt4 book ai didi

java - 此代码是否需要嵌套锁?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:58:09 25 4
gpt4 key购买 nike

我在一个类中有两个共享可变对象,其线程安全策略已定义为“线程安全”。

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);
}

我还为此类设置了一个策略,即 lockCal 必须始终在 lockSdf 之前获取。然而,这个类也是如此:

  • CAL 可以在没有 SDF 的情况下锁定和使用,在这种情况下 SDF 不会被锁定。
  • 除非同时使用 CAL,否则从不在方法中使用 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);
}

最佳答案

如果 SDF 只被一个已经获取了 lockCal 的线程使用,它一次只能被一个线程访问,即它是线程安全的即使您删除了 lockSdf 上的锁。

如果您选择依赖这个观察结果,您应该清楚地记录下来,这样 future 的维护程序员就不会开始在synchronized (lockCal) 之外使用SDF .

关于java - 此代码是否需要嵌套锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31847017/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com