任何人都可以解释为什么我们使用“最终的AtomicInteger count = this.count;”,以及为什么使用关键字final

时间:2013-10-23 17:53:00

标签: java methods final atomicinteger

public E poll() {
    final AtomicInteger count = this.count;
    if (count.get() == 0)
        return null;
    E x = null;
    int c = -1;
    final ReentrantLock takeLock = this.takeLock;
    takeLock.lock();
    try {
        if (count.get() > 0) {
            x = dequeue();
            c = count.getAndDecrement();
            if (c > 1)
                notEmpty.signal();
        }
    } finally {
        takeLock.unlock();
    }
    if (c == capacity)
        signalNotFull();
    return x;
}

任何人都可以解释为什么我们将this.count分配给局部变量,以及为什么局部变量声明为final?

3 个答案:

答案 0 :(得分:2)

  

任何人都可以解释为什么我们将this.count分配给局部变量

它可能会提高性能,因为访问本地变量比访问实例变量稍微便宜一些。 This post似乎支持这一点。但是,他们也说这是一种极端的优化,可能没有必要。

  

以及为什么局部变量声明为final?

似乎字段countsource code中也定义为final。他们可能只想通过将局部变量声明为final来保持一致。

答案 1 :(得分:0)

我在以下事情中可以看到的唯一价值:

final AtomicInteger count = this.count;

final ReentrantLock takeLock = this.takeLock;

是:如果原始成员未被声明为final,并且作者想要通知将来维护此代码的程序员 - 不以任何方式更改对这些对象的引用(这是实现的)通过final声明)。

<强>更新
此代码取自Doug Lea编写的LinkedBlockingQueue的实现。根据{{​​3}}的链接,Marko写道:

  

此外,即使有问题的成员变量不是易变的,也是如此   最后,这个成语与CPU缓存有关,就像从堆栈中读取一样   location比从随机堆读取更容易缓存   地点。本地变量最终的可能性也更高   绑定到CPU寄存器。

     

对于后一种情况,自JIT以来实际上存在一些争议   编译器通常会处理这些问题,但Doug Lea就是其中之一   坚持一般原则的人。

答案 2 :(得分:0)

我确信它与各种编译器优化有关。通常,这样的编译器提示不是必需的,因为理论上的编译器应该能够自己计算出这个特定的优化,但是JDK编写者可能对编​​译器的实际实际实现有更好的了解,因此知道这一点将创建更快的字节码。