如何安全地发布StringBuffer? [英] How to publish StringBuffer safely?
问题描述
由于 StringBuffer
是线程安全的,因此可以放心使用发表.考虑StringBuffer
的公共构造函数(来源):
Since StringBuffer
is thread safe it can safely be published. Consider the public constructor of StringBuffer
( sources ):
public StringBuffer() {
super(16);
}
其中super(16)
表示这一点:
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
其中值声明为
char[] value;
问题: :如何安全发布StringBuffer
?
我有以下课程:
public class Holder{
public final StringBuffer sb = new StringBuffer();
}
可以将其视为安全出版物吗? 我认为不能.
Can it be considered as safe-publication? I think, it cannot.
final
保证我们将看到引用sb
的新值.但是写入AbstractStringBuilder(int capacity)
中的sb
内部状态是不同步的.因此,没有happens-before
顺序,这依次意味着调用sb.append(2);
并在构造函数中写入value
时发生的value
读取是 racy .
final
guarantees that we'll see a fresh value of the reference sb
. But writing to the sb
's internal state within AbstractStringBuilder(int capacity)
is not synchronized. Therefore there's no happens-before
order which in turn means that read from value
occured when invoking sb.append(2);
and writing to value
in the constructor are racy.
您能帮助您理解吗?也许我错过了一些事情...
Can you help to understand this? Maybe I missed something...
推荐答案
您能帮助您理解吗?也许我错过了一些事情...
Can you help to understand this? Maybe I missed something...
JSR-133
之后的AFAIR,可以确保在实例化过程中像您的示例一样初始化的类的final
字段在竞争过程中没有竞争条件,并且在初始化之后仅公开正确的值
AFAIR after JSR-133
it is guaranteed that final
field of the class that is initialized like in your example is free from race condition during instantiation process and only the correct value will be exposed after init
更新::通过 Brian Goetz
在新的内存模型下,在构造函数中写入final字段与在另一个线程中对该对象的共享引用的初始加载之间存在类似事前发生的关系.构造函数完成后,对final字段(以及通过这些final字段间接可访问的变量)的所有写入均变为"frozen",并且保证在冻结后获得对该对象的引用的任何线程都可以查看所有冻结值.冰冻的田野.初始化final字段的写入操作不会在与构造函数关联的冻结之后进行重新排序.
Under the new memory model, there is something similar to a happens-before relationship between the write of a final field in a constructor and the initial load of a shared reference to that object in another thread. When the constructor completes, all of the writes to final fields (and to variables reachable indirectly through those final fields) become "frozen," and any thread that obtains a reference to that object after the freeze is guaranteed to see the frozen values for all frozen fields. Writes that initialize final fields will not be reordered with operations following the freeze associated with the constructor.
恕我直言,您的问题(和并发理解)非常好,因为它不是明显的语言/平台设计功能,并且仅在Java SE 5.0中已解决
IMHO your question (and concurrency understanding) is very good because it is not an obvious language / platform design feature and it was fixed only in Java SE 5.0
这篇关于如何安全地发布StringBuffer?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!