不要再卡了 2012-09-03 09:09
浏览 203
已采纳

ArrayBlockingQueue源码中为什么方法要用局部变量引用类变量

代码:
类变量:
private final E[] items;
private final ReentrantLock lock;
方法:
public void put(E o) throws InterruptedException {
if (o == null) throw new NullPointerException();
[b] final E[] items = this.items;
final ReentrantLock lock = this.lock;[/b]
lock.lockInterruptibly();
try {
try {
while (count == items.length)
notFull.await();
} catch (InterruptedException ie) {
notFull.signal(); // propagate to non-interrupted thread
throw ie;
}
insert(o);
} finally {
lock.unlock();
}
}
看黑体字部分 put方法中局部变量items和lock的使用有什么意义?

  • 写回答

3条回答 默认 最新

  • xpjsky 2012-09-04 00:37
    关注

    首先在JDK 7中,这段代码变成这样子了:
    [code="java"]
    final Object[] items;

    public void put(E e) throws InterruptedException {
    checkNotNull(e);
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
    while (count == items.length)
    notFull.await();
    insert(e);
    } finally {
    lock.unlock();
    }
    }
    [/code]
    然后做个实验:
    [code="java"]
    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;
    }
    [/code]
    然后javap一下,javap -p -c -s Test >> Test.log,得到如下代码:
    [code="java"]
    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

    [/code]

    两种写法唯一的区别,是getfield指令,getfield在对象内相对来说开销是比较廉价的,但前者(test方法)显然在代码可读性上,高出很多,如果不存在大量的实例变量引用,性能可以忽略不计,估计这也正是为什么JDK7采用这种简单的写法的原因吧。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波
  • ¥15 针对曲面部件的制孔路径规划,大家有什么思路吗
  • ¥15 钢筋实图交点识别,机器视觉代码
  • ¥15 如何在Linux系统中,但是在window系统上idea里面可以正常运行?(相关搜索:jar包)
  • ¥50 400g qsfp 光模块iphy方案
  • ¥15 两块ADC0804用proteus仿真时,出现异常
  • ¥15 关于风控系统,如何去选择