不要再卡了 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条)

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料