如果看过 JDK 源码的同学基本上都看到过类似于下面的语句:
对 "final ReentrantLock lock = this.lock;" 这种写法不知道大家是啥感受, 我当时看到是非常奇怪的, 于是就搜索了一下, 发现原作者对这种情况做了说明, 原文如下:
其中第一句就提到了这样做的原因是:"归根究底是由于内存模型与 OOP 之间的原则不一致", 后面基本上都是对这句话做出说明.
要理解上面的内容必须要对 Java 的内存模型有所了解, Java 的内存模型如下:
从上图我们可以知道 Thread Stack 是以过程函数为访问对象, 而不是以对象问访问的, 线程栈内只有基本变量和指向对象的引用 (对象本身是放在 heap 上).
从 java 内存模型中可以看出, method 只会存放对象引用 (this 指针), 不会存放对象中的信息, 只能再次通过 this 访问对象中的信息.
所以这种写法, 在访问 lock 的时候首先去访问 this 对象, 然后获取 lock 的引用, 最后再调用 lock 函数, 每次访问 lock 中的函数都是这 3 步.
但是如果采用将字段赋值给局部变量在使用, 之后就不需要访问 this 指针, 少了一步操作. 也就是说 this 对象和其他普通对象在函数没有任何区别
为了验证, 可以对代码进行反编译:
反编译的结果和内存模型推断出来的完全一致. 虽然采用将字段赋值给局部变量在以后使用中确实能够节省时间, 但是目前的 JDK 版本对于这种情况下都做了优化. 所以这种写法已经变成了 Doug Lea 习惯了.
来源: http://www.tuicool.com/articles/I3m6F3Z