Java:在双重检查习语中使用局部变量

Josh Bloch提到在双重检查习语中使用局部变量来提高性能(EJ,第2版.p284),并说示例代码在没有局部变量的情况下比他的机器快25%。 所以问题是,为什么它更快? 在局部变量版本的情况下,它访问实例变量3次,并且在正常情况下它访问实例变量4次。 这是“25%”增加背后的原因还是有其他原因?

编辑:仅在首次创建实例时才进行3或4次访问。 此后,它是1或2次。

EDIT2:检查此问题的已接受答案以查看示例代码。 我认为这是针对Java 6. 如何解决 Java中的“Double-Checked Locking is Broken”声明?

基本的是访问volatile变量比访问本地变量要慢。 声明局部变量时,基本上是在方法中缓存 volatile变量的值。

在正常(没有局部变量)的情况下,您正在访问volatile变量:

  1. synchronized子句之前的第一个if
  2. 在第二个if里面的synchronized子句
  3. 在第二个内部, if您为其分配值
  4. return声明中

现在,如果引入局部变量,则只能访问volatile变量三次:

  1. synchronized子句之前的第一个if分配局部变量时
  2. synchronized子句中的第二个if分配局部变量时
  3. 在第二个内部, if您为其分配值

通过返回局部变量,您不会在return语句中访问它,从而为您提供速度提升。

在正常情况下(已经初始化),只有一次读取volatile变量(相对昂贵)。 我想在这台机器上,这相当于他所看到的减少。 使用常规方法(即不使用局部变量),有两个读取(一个用于if ,一个用于return 。)