在ArrayBlockingQueue中,为什么将final成员字段复制到局部final变量中?

发布于 2024-09-04 12:34:22 字数 872 浏览 5 评论 0原文

ArrayBlockingQueue中,所有需要锁的方法在调用lock()之前都会将其复制到本地final变量中。

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();
    }
}

当字段 this.lockfinal 时,是否有任何理由将 this.lock 复制到局部变量 lock

此外,它还在操作之前使用 E[] 的本地副本:

private E extract() {
    final E[] items = this.items;
    E x = items[takeIndex];
    items[takeIndex] = null;
    takeIndex = inc(takeIndex);
    --count;
    notFull.signal();
    return x;
}

是否有任何理由将最终字段复制到本地最终变量?

In ArrayBlockingQueue, all the methods that require the lock copy it to a local final variable before calling 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();
    }
}

Is there any reason to copy this.lock to a local variable lock when the field this.lock is final?

Additionally, it also uses a local copy of E[] before acting on it:

private E extract() {
    final E[] items = this.items;
    E x = items[takeIndex];
    items[takeIndex] = null;
    takeIndex = inc(takeIndex);
    --count;
    notFull.signal();
    return x;
}

Is there any reason for copying a final field to a local final variable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最丧也最甜 2024-09-11 12:34:22

这是该课程的作者 Doug Lea 喜欢使用的一种极端优化。这是关于最近的帖子的帖子在 core-libs-dev 邮件列表上关于这个确切主题的邮件列表很好地回答了您的问题。

来自帖子:

...复制到本地产生最小的
字节码,对于低级代码,编写代码很好
离机器近一点

It's an extreme optimization Doug Lea, the author of the class, likes to use. Here's a post on a recent thread on the core-libs-dev mailing list about this exact subject which answers your question pretty well.

from the post:

...copying to locals produces the smallest
bytecode, and for low-level code it's nice to write code
that's a little closer to the machine

陈甜 2024-09-11 12:34:22

此帖子给出了一些答案。实质上:

  • 编译器无法轻松证明 Final 字段在方法内不会更改(由于反射/序列化等),
  • 大多数当前编译器实际上不会尝试,因此每次使用时都必须重新加载 Final 字段这可能会导致缓存未命中或页面错误,
  • 将其存储在局部变量中会强制 JVM 仅执行一次加载

This thread gives some answers. In substance:

  • the compiler can't easily prove that a final field does not change within a method (due to reflection / serialization etc.)
  • most current compilers actually don't try and would therefore have to reload the final field everytime it is used which could lead to a cache miss or a page fault
  • storing it in a local variable forces the JVM to perform only one load
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文