当前位置: 首页 > 知识库问答 >
问题:

构造函数中非线程安全集合的突变是否需要同步?

羊昊苍
2023-03-14

如果我决定使用一个非线程安全的集合并同步它的访问,我是否需要同步构造函数中的任何突变?例如,在下面的代码中,我知道对列表的引用在构造后对所有线程都是可见的,因为它是最终的。但我不知道这是否构成安全发布,因为构造函数中的add没有同步,而且它正在ArrayList的elementData数组中添加一个引用,这是非最终的。

private final List<Object> list;

public ListInConstructor()
{
    list = new ArrayList<>();
    // synchronize here?
    list.add(new Object());
}

public void mutate()
{
    synchronized (list)
    {
        if (list.checkSomething())
        {
            list.mutateSomething();
        }
    }
}

共有1个答案

易宣
2023-03-14

好的,这就是JLS§17.5.1关于这个主题的内容。

首先:

设o是一个对象,c是o的一个构造函数,其中写有一个final字段f。当c正常地或突然地退出时,在o的最后一个字段f上发生冻结作用。

public ListInConstructor() {
    list = new ArrayList<>();
    list.add(new Object());
} // the freeze action happens here!

我们有hb(w,f),这意味着我们在离开构造函数之前写入final字段。

r1是对最终字段的读取和取消引用(r1、r2)。这意味着r1读取final字段,r2然后读取该final字段的某个值。

我们还有一个动作(读或写,但不是对最终字段的读),它有hb(f,a)和mc(a,r1)。这意味着该操作发生在构造函数之后,但可以在之后被读取的r1看到。

旁白:HotSpot通过在包含final字段的任何构造函数的末尾放置内存屏障来实现final字段语义,从而在任何情况下都保证该属性。这是否只是一个优化(最好只对一个屏障进行优化,并且尽可能远离写)是另一个问题。

 类似资料:
  • 我有一个任务,我需要添加2个构造函数,并从中分离出来,还列出了变异子。然而,我认为大多数构造函数都是变种人:正如本文所示。所以我很困惑,对于变异子方法,我需要做什么?目前,我为施工人员提供以下服务: 根据评论: 以下是我尝试过的,但它会导致以下错误 PrintStream类型中的print(布尔)方法不适用于参数(void) 在这条主线上: 方法如下:

  • 问题内容: 我有两个类,和,扩展了前一个类。 具有以下构造函数: 我将注意到所有实例变量都已设置为private。 同时,具有以下构造函数: 但是,这为我的构造函数引发了“找不到符号”错误。 我尝试使用,但是我的超类的私有范围阻止了这种情况。 我发现向我的构造函数中添加字段并允许我调用超级构造函数,但是我想知道是否存在一种无需在子类构造函数中传递其所有参数的情况下调用超级构造函数的方法? 问题答案

  • 我看到了不同的PHP二进制文件,比如非线程或线程安全? 这是什么意思? 这些软件包之间有什么区别?

  • 本文向大家介绍哪些集合类是线程安全的?相关面试题,主要包含被问及哪些集合类是线程安全的?时的应答技巧和注意事项,需要的朋友参考一下 Vector、Hashtable、Stack 都是线程安全的,而像 HashMap 则是非线程安全的,不过在 JDK 1.5 之后随着 Java. util. concurrent 并发包的出现,它们也有了自己对应的线程安全类,比如 HashMap 对应的线程安全类就

  • 问题内容: 除了* 使用如下所示的反射检查 之外 ,是否有任何方法 要求 类具有默认(无参数)构造函数?(以下方法可以工作,但是很hacky,反射速度很慢) * 问题答案: 您可以为此构建一个注释处理器。注释处理器是在编译时运行的编译器插件。它们的错误显示为编译器错误,甚至可能停止构建。 这是一个示例代码(尽管我没有运行它): 如果引入注释(例如RequiresDefaultAnnotation)

  • 有人告诉我,包含getter和setter的可序列化对象需要一个空构造函数,如下所示: 告诉我的原因是,这允许使用setter构造对象。但是,我发现,当定义如下时: 当通过WCF服务引用作为代理类提供时,无需调用构造函数即可构造: 问题: 在声明