java - 如果我使用 32 位原语和我的函数幂等,为什么我可以跳过 DCL 的任何同步?

标签 java multithreading concurrency primitive idempotent

我读过以下经典名篇:The "Double-Checked Locking is Broken" Declaration

我有一个问题:

In fact, assuming that the computeHashCode function always returned the same result and had no side effects (i.e., idempotent), you could even get rid of all of the synchronization.

// Lazy initialization 32-bit primitives
// Thread-safe if computeHashCode is idempotent
class Foo { 
  private int cachedHashCode = 0;
  public int hashCode() {
    int h = cachedHashCode;
    if (h == 0) {
      h = computeHashCode();
      cachedHashCode = h;
      }
    return h;
    }
  // other functions and members...
  }

这篇文章是为 java 4 编写的。它对 java 8+ 仍然有效吗?

computeHashCode()是真的吗?只会被调用一次?

最佳答案

不,它可以执行多次。同步会将更改“刷新”到其他线程,如果没有它,一个线程中所做的更改理论上永远无法在该线程之外进行通信。

但是,文章并没有说 computeHashCode 将被调用一次,只是竞争条件不会导致任何问题。 int 写入保证是原子的,如果 computeHashCode 是幂等的(这要求类及其字段实际上是最终的),您只需用相同的值,所以不会发生任何不好的事情。

关于java - 如果我使用 32 位原语和我的函数幂等,为什么我可以跳过 DCL 的任何同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58013534/

相关文章:

java - 开始新项目后,MainActivity无法手动构建

java - 配置为这样做时,Spring Boot 不使用 HSQLDB 的基于文件的数据库

multithreading - 在 Clozure Common Lisp 中生成多个进程来处理许多基于套接字的连接

JAVA - 从启动器调用时外部 exe 锁定

java - 如何在一天后自动终止计时器?

swift - 在 Swift 中,当两个线程获取并设置一个非线程安全属性时会发生什么?

go - 即使使用互斥锁,打印结构字段时也会出现竞争条件

java - ConcurrentHashMap 的预期 NullPointerException 未显示

java - 如何将数组中的对象打印到文本字段

c++ - 如何同时使用两个CameraCaptureUI(UWP/C++)