当前位置: 首页 > 面试题库 >

为什么它不直接使用实例字段,而是将其分配给局部变量?

乔宏峻
2023-03-14
问题内容

我正在阅读的源代码java.util.concurrent.ArrayBlockingQueue,并发现了一些我不理解的代码:

private final ReentrantLock lock;

public boolean offer(E e) {
    if (e == null) throw new NullPointerException();
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        if (count == items.length)
            return false;
        else {
            insert(e);
            return true;
        }
    } finally {
        lock.unlock();
    }
}

注意这一行:

final ReentrantLock lock = this.lock;

为什么不this.lock直接使用它,而是将其分配给局部变量?


问题答案:

可能是出于 html" target="_blank">优化 目的吗?

可能可以通过JIT编译器更轻松地将局部变量直接分配给寄存器。

至少在Android中,对于API的第一个版本,访问局部变量比访问实例变量便宜(不能代表较新的版本)。普通的Java可能是相同的,在某些情况下使用本地是有意义的。

实际上,在这里找到一个确认这一点的线程。提取:

这是Doug
Lea流行的编码样式。这是一个极端的优化,可能没有必要。您可以期望JIT进行相同的优化。(您可以尝试自己检查机器代码!)不过,复制到本地代码会生成最小的字节码,对于低级代码,最好编写更接近机器的代码。



 类似资料:
  • 问题内容: 这是JDK的类方法。作者为什么将字段分配给局部变量? 上面和下面之间有什么区别?这与线程安全有关吗? 问题答案: 为了稍微扩展一下Michael的答案,我希望它可以确保该方法永不返回,而且还可以提供所提到的性能优势。 给出以下代码: 至少从理论上讲,在多线程代码中,可以将字段设置为第一次读取()和第二次读取之间,然后将其返回。我没有看过其余的代码,但是我假设还有其他可能被分配的地方。对

  • 问题内容: 当我从中读取源代码时,我很困惑为什么它编写了这样的代码: 为什么使用别名而不是直接使用field变量,如下所示: 有人可以给出合理的解释吗? 问题答案: 如果您是从上下文中看这段代码,那么对于“别名”将没有很好的解释。它仅仅是冗余代码或不良的代码样式。 但是上下文是可以被子类化的类,它需要在多线程上下文中工作。 线索是,在宣布IS 。这意味着子类有可能进入并分配给。考虑到这种可能性,实

  • 当我从,我不明白它为什么会这样写代码: 为什么它使用别名,而不是直接在中使用字段变量

  • 问题内容: 我正在阅读的来源,发现如果该方法中多次使用该值,则几乎总是将字段分配给局部变量。 由于此类已记录为不是线程安全的,并且字段也不是可变的,所以这有什么意义?它会使代码更有效吗? 问题答案: 通过将成员字段放入本地范围(即当前堆栈框架)中,可以为整个方法执行固定引用。因此,每次使用时,您对同一对象都有相同的引用。 无需将其置于本地范围内,对字段的每次访问均通过引用(隐式或显式)进行。因此,

  • 问题内容: 浏览Java API源代码时,我经常看到方法参数已重新分配给局部变量。为什么要这样做? 这在java.util.HashMap中 问题答案: 这是线程安全性/更好性能的规则。在易失。如果将变量分配给局部变量,它将变为局部堆栈变量,该变量自动是线程安全的。而且,修改局部堆栈变量不会强制“先发生”,因此在使用它时不会产生同步损失(与之不同的是,每次读/写操作都会导致易失性,这会花费您获取/

  • 问题内容: 有关语法的简单问题。为什么限制这样的表达式: 并只允许以下内容: ? 问题答案: 这是因为方法引用或lambda表达式的目标类型应该是功能接口。仅基于此,运行时将创建提供给定功能接口的实现的类的实例。将lambda或方法引用视为概念。将其分配给功能接口类型将赋予其具体含义。 此外,特定的lambda或方法引用可以具有多个功能接口作为其目标类型。例如,考虑以下lamda: 这个lambd