首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用最终字段的成本

使用最终字段的成本
EN

Stack Overflow用户
提问于 2014-05-08 04:00:42
回答 1查看 1.2K关注 0票数 20

我们知道,将字段设为final通常是一个好主意,因为我们获得了线程安全性和不变性,这使得代码更容易推理。我很好奇是否有相关的性能成本。

Java Memory Model保证了这个final Field Semantics

一个线程只能在对象完全初始化后才能看到对该对象的引用,它可以保证看到该对象的最终字段的正确初始化值。

这意味着对于像这样的类

class X {
    X(int a) {
        this.a = a;
    }
    final int a;

    static X instance;
}   

每当Thread 1创建一个这样的实例时

X.instance = new X(43);
while (true) doSomethingEventuallyEvictingCache();

线程2看到了它

 while (X.instance == null) {
      doSomethingEventuallyEvictingCache();
 }
 System.out.println(X.instance.a);

它必须打印43。在没有final修饰符的情况下,JIT或CPU可以重新排序存储(首先存储X.instance,然后设置a=43),Thread2可以看到默认初始化值并打印0。

当JIT看到final时,它显然会克制住不重新排序。但它也必须迫使CPU服从命令。是否存在相关的性能损失?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-08 04:07:48

是否存在相关的性能损失?

如果您查看一下JIT编译器的源代码,您将在文件src/share/vm/opto/parse1.cpp中找到关于最终成员变量的以下注释

这个方法(根据Java的规则,它必须是一个构造函数)写了一个final。在构造函数发布对新构造函数对象的引用之后,必须在任何代码之前将所有初始化的效果提交到内存中。而不是等待发布,我们只需在此处阻止写入。我们不是只对那些需要完成的写操作设置障碍,而是强制所有写操作都完成。

如果有最终成员变量,编译器会发出额外的指令。最有可能的是,这些额外的指令会导致性能损失。但目前还不清楚,这种影响是否对任何应用程序都有重大影响。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23527252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档