gpt4 book ai didi

java - 缓存的哈希码字段应该有哪些修饰符?

转载 作者:行者123 更新时间:2023-12-03 13:11:48 24 4
gpt4 key购买 nike

给定一个不可变对象(immutable对象),有时缓存其哈希码是有意义的。下面是一个例子。

在示例中,我意识到缓存比重新计算 hashCode 更昂贵。

  public class ImmutableObject{
final int immutableField1;
final String immutableField2;

//volatile? transient? WeakReference?
private Integer cachedHashCode = null;

@Override
public int hashCode() {
Integer ret=cachedHashCode;
if(ret == null) {
ret = immutableField1;
ret = 31 * ret + immutableField2.hashCode();
}
cachedHashCode = ret;
return ret;
}
// constructor, equals, other methods...

}

什么修饰符 cachedHashCode需要?
  • Volatile:有效的 Java 建议在此处使用 volatile 修饰符 (how caching hashcode works in Java as suggested by Joshua Bloch in effective java?)。由于类是不可变的,在什么情况下非严格的执行顺序是危险的?仅仅是为了防止hashCode的冗余计算吗?
  • transient :如果哈希码是派生的,那么重新计算它几乎肯定比序列化/反序列化它更便宜。你想在什么条件下序列化一个哈希码?
  • WeakReference:如果类只有几个字段,但 hashCode 缓存仍然(以某种方式)值得,缓存的 hashcode 可能会显着增加每个对象的内存占用。那么缓存应该是一个弱引用吗? WeakReference 是否总是至少占用与缓存的 int 一样多的空间?
  • 最佳答案

    易 volatile 的:

    是的。这确保了在赋值之后,它被写入内存并且程序的所有其他线程都会看到它。如果没有 volatile 或 synchronized block ,则无法保证写入的值对其他人可见。这种魔法是在 Java 内存模型中定义的。

    短暂的:

    是的。但是,仅对标记为可序列化的类有意义。你永远不想序列化容易重新计算的东西。也许只有重新计算需要付出很多努力,它才有意义。这是典型的空间/时间权衡决策。

    弱引用:

    不,这会增加更多开销。如果你想安全内存更改为 int 值。添加一个额外的标志或定义一个特殊的数字,用于“需要计算”的目的。

    关于java - 缓存的哈希码字段应该有哪些修饰符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30133619/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com