【发布时间】:2016-04-06 09:58:22
【问题描述】:
由于StringBuffer 是线程安全的,因此可以安全地发布。考虑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();
}
它可以被视为安全发布吗? 我认为,它不能。
final 保证我们将看到引用 sb 的新值。但是在AbstractStringBuilder(int capacity) 中写入sb 的内部状态是不同步的。因此,没有happens-before 顺序,这反过来意味着在构造函数中调用sb.append(2); 和写入value 时发生从value 的读取是racy。
你能帮忙理解一下吗?也许我错过了什么......
【问题讨论】:
-
你的意思是
sb是一个实例变量还是应该是静态的? -
如果您想要一个不时更改的文本/字符串的线程安全提供程序,请使用
AtomicReference<String>。 StringBuffer 用于并发追加,这是一个罕见的用例。 -
@Paolo 不,它完全是一个实例变量。静态初始化发生在初始化需要跨 JVM 锁定的类时,从而确保内存一致性。
-
我认为您对这里的安全或不安全感到困惑。构造函数将在引用分配之前完成,在这方面有一个happens-before:如果您可以看到引用,那么您也可以看到构造函数中发生的所有事情。唯一不安全的做法是将构造函数中的
this泄漏到其他地方,而StringBuilder不会发生这种情况。 -
@JoopEggen 问题不完全是关于寻找另一种方式。我只是想了解使用 StringBuffer 是否安全。
标签: java multithreading safe-publication