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?
答案 0 :(得分:2)
任何人都可以解释为什么我们将this.count分配给局部变量
它可能会提高性能,因为访问本地变量比访问实例变量稍微便宜一些。 This post似乎支持这一点。但是,他们也说这是一种极端的优化,可能没有必要。
以及为什么局部变量声明为final?
似乎字段count
在source 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编写者可能对编译器的实际实际实现有更好的了解,因此知道这一点将创建更快的字节码。