gpt4 book ai didi

java - 了解 JVM 对不可变对象(immutable对象)的保证

转载 作者:行者123 更新时间:2023-11-30 08:32:05 25 4
gpt4 key购买 nike

Java 并发实践有以下例子:

@ThreadSafe
public class VolatileCachedFactorizer implements Servlet {
private volatile OneValueCache cache = new OneValueCache(null, null);

public void service(ServletRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = cache.getFactors(i);
if (factors == null) {
factors = factor(i);
cache = new OneValueCache(i, factors);
}
encodeIntoResponse(resp, factors);
}
}
}

OneValueCache 是不可变的。

据我所知,使用 volatile 可确保所有线程都能看到存储在 cache 变量中的最新引用。

同时它说

Immutable objects can be used safely by any thread without additional synchronization, even when synchronization is not used to publish them.

对我来说,它说我们实际上不需要上面用于同步的 volatile

JLS 还有如下例子:

class FinalFieldExample {
final int x;
int y;

static FinalFieldExample f;

public FinalFieldExample() {
x = 3;
y = 4;
}

static void writer() {
f = new FinalFieldExample();
}

static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}

他们不对字段f 使用volatile。这是否意味着其他线程可以将 f 视为 null 而永远看不到创建的实例?

谁能解释一下?

最佳答案

From what I understand using volatile ensures that all threads see up-to-date reference stored in the cache variable.

没错,但是这个概念适用于变量 while 引用自 JCiP 的语句

Immutable objects can be used safely by any thread without additional synchronization, even when synchronization is not used to publish them.

不适用于变量,但适用于对象本身。这意味着一个线程将始终看到一个完全构造的对象,而不会发生任何数据竞争,这与它的发布方式无关,因为正如 JCiP 所述

Immutable objects can be published through any mechanism.

现在关于你的第二个例子:

Doesn't it mean that other threads can see f as null and never see the created instance?

没错。如果一个线程调用 writer(),其他线程可能会将 f 视为 null 或将 f.y 视为 0 因为它不尊重安全发布:

3.5.3. Safe Publication Idioms

To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:

  • Initializing an object reference from a static initializer;
  • Storing a reference to it into a volatile field or AtomicReference;
  • Storing a reference to it into a final field of a properly constructed > object; or
  • Storing a reference to it into a field that is properly guarded by a lock.

关于java - 了解 JVM 对不可变对象(immutable对象)的保证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40294186/

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