简体   繁体   English

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

[英]Using a local variable when initializing a static variable

In the source code of java.util.Scanner I've found these static utility methods: java.util.Scanner的源代码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;
}

Why it was done in such a complex way and not just, say, 为什么它以如此复杂的方式完成而不仅仅是,比方说,

private static Pattern linePattern() {
    if (linePattern == null)
        linePattern = Pattern.compile(LINE_PATTERN);
    return linePattern;
}

What was the point of using a local variable ( lp ) here? 在这里使用局部变量( lp )有什么意义? Is this some kind of optimization technique? 这是某种优化技术吗? Or maybe precaution against a concurrent modification? 或者可能是针对并发修改的预防措施? But linePattern cannot be set to null again as this method is the only place where it is modified. 但是linePattern不能再次设置为null ,因为此方法是修改它的唯一位置。

I believe it's all about volatile keyword used with linePattern and separatorPattern fields 我相信所有关于与linePatternseparatorPattern字段一起使用的volatile关键字

private static volatile Pattern separatorPattern;
private static volatile Pattern linePattern;

Due to specification 由于规格

The Java programming language allows threads to access shared variables (§17.1). Java编程语言允许线程访问共享变量(第17.1节)。 As a rule, to ensure that shared variables are consistently and reliably updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that, conventionally, enforces mutual exclusion for those shared variables. 通常,为了确保共享变量一致且可靠地更新,线程应确保通过获取锁定来独占使用此类变量,该锁定通常会对这些共享变量实施互斥。

The Java programming language provides a second mechanism, volatile fields, that is more convenient than locking for some purposes. Java编程语言提供了第二种机制,即volatile字段,比某些用途的锁定更方便。

A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable 字段可以声明为volatile,在这种情况下,Java Memory Model可确保所有线程都看到变量的一致值

Also here we can read that 我们也可以在这里阅读

Declaring a volatile Java variable means: 声明一个易变的Java变量意味着:

  • The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory"; 这个变量的值永远不会被线程本地缓存:所有读写都将直接进入“主存”;

  • Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself. 对变量的访问就像包含在同步块中一样,自身同步。

That's why they firstly try to directly read field's value and then overwrite it with new value 这就是为什么他们首先尝试直接读取字段的值然后用新值覆盖它

I think they want to avoid reading from the volatile field twice. 我认为他们希望避免两次从volatile场中读取。

  • once to check if it is null 一次检查是否为null
  • once for the return 一次return

In their version, they only 在他们的版本中,他们只是

  • once read it into a local variable 一旦将其读入局部变量
  • confirm that the local variable is not null 确认局部变量不为null
  • return that local variable 返回该局部变量

The optimization is for the "happy path" that happens incredibly more often than the "initial setup path" that only happens once -- or at most a few times if the method is called concurrently before it has finished the initialization. 优化是针对“快乐路径”,其发生频率比“初始设置路径”更频繁地发生,其仅发生一次 - 或者如果在完成初始化之前同时调用该方法,则最多几次。

Or maybe precaution against a concurrent modification? 或者可能是针对并发修改的预防措施?

There is no such precaution. 没有这样的预防措施。 If you call linePattern concurrently before it has finished setting the static volatile field, the pattern will be created multiple times (but that's fine), different instances will be returned and a random one of those will be chosen to stick around (that's also fine, since they are equivalent). 如果在设置静态volatile字段之前同时调用linePattern ,则会多次创建模式(但没关系),将返回不同的实例,并选择随机的实例(这也很好,因为它们是等价的)。

Any measures to guard against that would only add cost to our "happy path" so should only be done in situations were the instance must really be a singleton for some reason. 任何防范这种情况的措施只会增加我们“快乐路径”的成本,所以只有在实例因某种原因必须真正成为单身人士的情况下才应该这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM