阅读课程领域的费用

时间:2015-11-27 07:01:59

标签: java performance

Java 7

我正在阅读J. Bloch的有效Java,现在我正在关于初始化字段laziliy的部分。他引用了所谓的复核成语,如下所示:

public static void main(String[] args){

        Test t = new Test();
        long now = System.nanoTime();
        t.getT();
        long invokationTime = System.nanoTime() - now;
        System.out.println(invokationTime); //Prints 3299 averagely
    }

    private static class Test{
        private volatile Test field;

        public Test getT(){
            Test result = field;  // <----- Note the local variable here
            if(result != null){
                synchronized (this) {
                    result = field;
                    if (result == null)
                        field = result = new Test();
                }
            }
            return result;
        }
    }

DEMO

他给出了使用局部变量的以下解释:

  

这个变量的作用是什么   确保字段 只读一次 ,这是常见的情况   已初始化。

现在,让我们考虑以下代码:

public static void main(String[] args){

    Test t = new Test();
    long now = System.nanoTime();
    t.getT();
    long invokationTime = System.nanoTime() - now;
    System.out.println(invokationTime);  //Prints 3101 averagely
}

private static class Test{
    private volatile Test field;

    public Test getT(){
        if(field != null){
            synchronized (this) {
                if (field == null)
                    field = new Test();
            }
        }
        return field;
    }
}

DEMO

在我的机器上,第二个lazy-init方法更快。但是在Ideone的机器上,他们大约花了7985和10630,就像J.布洛赫说的那样。那么使用这些局部变量进行优化是否值得?据我所知,读取和写入变量的成本几乎相等。

所以我们只有在方法主要由这种轻量级操作组成时才应该担心,对吗?

1 个答案:

答案 0 :(得分:1)

这有点值得,因为您已经确定急切的加载和同步都太昂贵了。但实际上,它几乎肯定不是。您实际需要双重检查锁定代码的情况往往是非锁定数据结构和事物。高性能代码的良好设计往往会将其推向孤立的地方,因此每次触摸代码时都不会将自己射入脚中。