java - ConcurrentHashMap 中的本地引用

标签 java concurrency

在ConcurrentHashMap中,段被标记为最终的(因此永远不会改变),但是方法ensureSegment创建了段的方法本地副本,ss,在该副本上操作。

有人知道这个目的吗?我们能得到什么好处?

更新:

我从google搜索,得到一页解释JDK7中的ConcurrentHashMap The Concurrency Of ConcurrentHashMap ,以下为摘录

Local References

Even though segments is marked final (and thus will never change), Doug Lea prudently creates a method-local copy, ss, of segments upon which to operate. Such defensive programming allows a programmer to not worry about otherwise-volatile instance member references changing during execution of a method (i.e. inconsistent reads). Of course, this is simply a new reference and does not prevent your method from seeing changes to the referent.

谁能解释一下粗体文字吗?

最佳答案

访问 final 字段和访问保存 final 字段值副本的局部变量之间没有语义差异。然而,在性能关键代码中将字段复制到局部变量中是一种既定模式。

即使在没有影响的情况下(取决于 HotSpot 优化器的状态),它也会在方法代码中至少节省一些字节。

对实例字段的每次访问,无论是否是final(唯一的异常(exception)是编译时常量),都将被编译为两条指令,首先推送this > 通过 aload_0 引用操作数堆栈,然后执行 getfield操作,它有一个描述该字段的常量池条目的两个字节索引。换句话说,每个字段访问需要方法代码中的四个字节,而如果变量是方法的前四个字节之一(将 this 算作局部变量),则读取局部变量只需要一个字节,这里就是这种情况(参见 aload_n )。

因此,当要多次访问字段值时,将字段值存储在局部变量中是一种很好的行为,可以防止可变变量发生更改,并避免 volatile 读取和读取的成本即使它已经过时(如 final 字段的情况),仍然不会造成伤害,因为它甚至会生成更紧凑的字节代码。在简单的解释执行中,即在优化器启动之前,单个局部变量访问可能确实比通过 this 实例绕行更快。

关于java - ConcurrentHashMap 中的本地引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31560098/

相关文章:

java - 有什么方法可以在 .jar 文件中设置 Java 系统属性,以便它们具有默认值但可以在命令行中覆盖?

java - 我能以某种方式解决 ResourceIterator 惰性的这一特定方面吗?

java - CountDownLatch 同步

java - 在 WebLogic 上添加服务器启动参数 -DUseSunHttpHandler=true

java - 使用 js/jquery/java/active x 或其他方式拍摄 <div> 的快照?

java - Spring 安全出版

java - 在 Scala 中学习并发时出现 NullPointerException

java - CompletableFuture 多线程、单线程并发,还是两者兼而有之?

java - 为什么在 Java 中 `char` 转换为 `int` 而不是 `short` 或 `byte`?

java - 无需单击即可切换 JToggleButton,并取消设置样式