关于java ArrayBlockingQueue 源码解析的小疑惑
今天在学习ArrayBlockQueue源码的时候有一个小疑惑 如代码:
?
/** The queued items */ final Object[] items; //实例变量 /** * Extracts element at current take position, advances, and signals. * Call only when holding lock. */ private E extract() { final Object[] items = this.items; E x = this.<E>cast(items[takeIndex]); items[takeIndex] = null; takeIndex = inc(takeIndex); --count; notFull.signal();
?
?
就是在代码的第9行:final Object[] items=this.items;
还有很多方法都是这种形式:在方法中要用到某个实例变量的时候采取的方法是先新建一个引用变量来引用原来的对象,而不是直接使用(这里即为this.items)。在网上查看了很多文章最后在iteye的问答区找到了答案
原链接http://www.iteye.com/problems/87918 ? ? ? ?
它举了个例子
?
final Object[] items = new Object[10]; public void test() { if(items.length == 0) { } int i = items.length; } public void test2() { final Object[] items = this.items; if(items.length == 0) { } int i = items.length; }
?
?然后javap一下,javap -p -c -s Test >> Test.log,得到如下代码:
?
public void test(); Signature: ()V Code: 0: aload_0 1: getfield #3 // Field items:[Ljava/lang/Object; 4: arraylength 5: ifne 8 8: aload_0 9: getfield #3 // Field items:[Ljava/lang/Object; 12: arraylength 13: istore_1 14: return public void test2(); Signature: ()V Code: 0: aload_0 1: getfield #3 // Field items:[Ljava/lang/Object; 4: astore_1 5: aload_1 //load 局部变量 items 6: arraylength 7: ifne 10 10: aload_1 // 这里少了getfield,因为aload_1 load的就是items 11: arraylength 12: istore_2 13: return
?
?最终原因:两种写法唯一的区别,是getfield指令,getfield在对象内相对来说开销是比较廉价的,但前者(test方法)显然在代码可读性上,高出很多,如果不存在大量的实例变量引用,性能可以忽略不计,估计这也正是为什么JDK7采用这种简单的写法的原因吧。
?
重点在于 如果用 this.items 的话 字节码的表现是 aload_0,getfield 如果先复制的话 直接就是 aload_1;估计getfield 的效率比aload_1低所以才会这样使用。
?
由于我对这些JVM了解的还很少,欢迎各位指教,如果能推介一两本书籍深入了解JVM的话感激不尽!
?
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。