如何安全发布StringBuffer?

St.*_*rio 5 java multithreading safe-publication

由于StringBuffer是线程安全的,因此可以安全地发布.考虑StringBuffer(来源)的公共构造函数:

public StringBuffer() {
    super(16);
}
Run Code Online (Sandbox Code Playgroud)

在哪里super(16)指定这个:

AbstractStringBuilder(int capacity) {
    value = new char[capacity];
}
Run Code Online (Sandbox Code Playgroud)

其中值声明为

char[] value;
Run Code Online (Sandbox Code Playgroud)

问题:如何StringBuffer安全发布?

我有以下课程:

public class Holder{
     public final StringBuffer sb = new StringBuffer();
}
Run Code Online (Sandbox Code Playgroud)

它可以被视为安全出版物吗?我想,它不可能.

final保证我们会看到参考的新值sb.但写入sb内部状态AbstractStringBuilder(int capacity)并不是同步的.因此,有没有happens-before这反过来又意味着,从读命令value调用发生时,sb.append(2);并写入value在构造函数是活泼的.

你能帮忙理解这个吗?也许我错过了什么......

Coo*_*tri 4

你能帮助理解这一点吗?也许我错过了什么...

AFAIRJSR-133保证像final您的示例中那样初始化的类的字段在实例化过程中不会出现竞争条件,并且在初始化后只会暴露正确的值

更新:通过布莱恩·戈茨

在新的内存模型下,构造函数中final字段的写入与另一个线程中对该对象的共享引用的初始加载之间存在类似于happens-before关系。当构造函数完成时,对 Final 字段(以及通过这些 Final 字段可间接访问的变量)的所有写入都将被“冻结”,并且在冻结后获取对该对象的引用的任何线程都保证能看到所有对象的冻结值。冰冻的田野。初始化最终字段的写入不会与构造函数关联的冻结之后的操作重新排序。

恕我直言,你的问题(和并发理解)非常好,因为它不是一个明显的语言/平台设计功能,并且仅在 Java SE 5.0 中修复