初始化静态变量时使用局部变量

Joh*_*ane 7 java variables static initialization

java.util.Scanner我找到这些静态实用程序方法的源代码中:

private static Pattern separatorPattern() {
    Pattern sp = separatorPattern;
    if (sp == null)
        separatorPattern = sp = Pattern.compile(LINE_SEPARATOR_PATTERN);
    return sp;
}

private static Pattern linePattern() {
    Pattern lp = linePattern;
    if (lp == null)
        linePattern = lp = Pattern.compile(LINE_PATTERN);
    return lp;
}
Run Code Online (Sandbox Code Playgroud)

为什么它以如此复杂的方式完成而不仅仅是,比方说,

private static Pattern linePattern() {
    if (linePattern == null)
        linePattern = Pattern.compile(LINE_PATTERN);
    return linePattern;
}
Run Code Online (Sandbox Code Playgroud)

lp在这里使用局部变量()有什么意义?这是某种优化技术吗?或者可能是针对并发修改的预防措施?但linePattern不能null再次设置,因为此方法是唯一修改它的地方.

Thi*_*ilo 2

我认为他们想避免volatile两次实地阅读。

  • 一次检查是否是null
  • 一次为return

在他们的版本中,他们只

  • 一旦将其读入局部变量
  • 确认局部变量不为空
  • 返回该局部变量

优化是针对“快乐路径”的,它比仅发生一次的“初始设置路径”发生的频率要高得多,或者如果在完成初始化之前并发调用该方法,则最多发生几次。

或者也许可以预防并发修改?

没有这样的预防措施。如果您linePattern在完成设置静态易失性字段之前并发调用,则该模式将被创建多次(但这很好),将返回不同的实例,并且将选择其中的随机一个来保留(这也很好,因为它们是等价的)。

任何防止这种情况的措施只会增加我们“幸福之路”的成本,因此只能在实例由于某种原因必须确实是单例的情况下才应该采取。