如何安全地发布StringBuffer? [英] How to publish StringBuffer safely?

查看:124
本文介绍了如何安全地发布StringBuffer?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆