【发布时间】:2021-03-21 10:21:12
【问题描述】:
在 Brian Goetz 等人的《Java Concurrency in Practice》一书中:
如果您不能确保发布共享引用发生在另一个线程加载该共享引用之前,那么可以重新排序对新对象的引用的写入(从使用对象的线程的角度来看)写入其字段。在这种情况下,另一个线程可能会看到对象引用的最新值,但该对象的部分或全部状态(部分构造的对象)的值已过时。
这是否意味着:在线程发布对象中,对新对象的引用的写入不会随着对其字段的写入而重新排序;对其字段的写入发生在引用的写入之前。但是,该发布线程可能会在刷新更新的对象字段之前刷新对主内存的更新引用。因此,消费对象的线程可能会看到对象的非空引用,但会看到对象字段的过时值?从这个意义上说,为消费线程重新排序了操作。
【问题讨论】:
-
请理解缓存总是一致的。所以在 1 cpu 上的 cacheline 上进行更改之前,它将首先在所有其他缓存上失效。因此,在写入高速缓存行之后,一个或多个 CPU 无法看到这种变化是不可能的。现代 CPU 不使用刷新和从主存储器读取。还要了解在常规加载/存储和易失性之间写入缓存没有区别。重新排序的原因是编译器或处理器,因为根据处理器的类型,存储/加载可能会乱序执行。
标签: java concurrency happens-before