gpt4 book ai didi

java - 如何将对象上的字段设置为 Final 以避免线程在同一对象上看到空引用?

转载 作者:行者123 更新时间:2023-11-30 07:13:21 25 4
gpt4 key购买 nike

Java 并发实践中的摘要/片段-

// Unsafe publication
public Holder holder;

public void initialize(){
holder = new holder(42);
}

Two things can go wrong with improperly published objects. Other threads could see a stale value for the holder field, and thus see a null reference or other older value even though a value has been placed in holder. But far worse, other threads could see an up-todate value for the holder reference, but stale values for the state of the Holder. To make things even less predictable, a thread may see a stale value the first time it reads a field and then a more up-to-date value the next time, which is why assertSanity can throw AssertionError.

对象引用对另一个线程可见并不一定意味着该对象的状态对消费线程可见

public class Holder{
private int n;

public Holder(int n) {
this.n = n;
}

public void assertSanity(){
if (n != n)
throw new AssertionError("This statement is false.");
}
}

当然,解决这个问题的方法之一是做/制作

public volatile Holder holder;

作者提出了一种不同的方法-

If Holder were immutable, assertSanity could not throw AssertionError, even if the Holder was not properly published.)

public class Holder{
private final int n;
//...
}

但是怎么办呢?不安全的出版物仍然存在。我认为线程仍然有可能在持有者上获得null引用。请提出建议。

最佳答案

jls 描述了 Final 字段的特殊语义

https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5

final fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads. [...]. final fields must be used correctly to provide a guarantee of immutability.

但我建议你阅读整个第17.5章

“必须正确使用”是指构造函数实际上已经结束(并且没有转义this)并且没有摆弄反射。

翻译自http://www.angelikalanger.com/Articles/EffectiveJava/38.JMM-Overview/38.JMM-Overview.html即:

The end of the constructor causes a partial flush, writing all final variables and dependend objects into memory. [...]. The first reading access of a final variable causes a partial refresh, loading the final variables and depending objects from memory. Another refersh does not occur [...].

关于java - 如何将对象上的字段设置为 Final 以避免线程在同一对象上看到空引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38813281/

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