gpt4 book ai didi

java - 在同一个函数的 synchronized() block 中初始化后,能否在 synchronized() 之外安全地使用 Java 集合?

转载 作者:行者123 更新时间:2023-12-04 05:50:36 26 4
gpt4 key购买 nike

以下代码是否被认为是线程安全的,即:写入列表是否保证先于读取列表?我一直在试图了解这在 Java 内存模型中是否被认为是安全的,但目前还不清楚。

通过基本的流程分析,看起来可以保证所有可能的线程在到达下面的 for 循环之前都必须通过 synchronized 初始化程序 block ,但是对该列表的迭代是确定性和线程安全的吗?我不确定是否保证初始化先于使用下面的列表。

假设这是类中唯一的方法。我知道在同步块(synchronized block)内移动迭代可以保证线程安全,但我更想知道这个构造是否安全。

另外,假设列表永远不会逃脱类。

Java 内存模型在此处的 JLS 中进行了解释:http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4

private List<Foo> list;
private final Object monitor = new Object();

public void bar() {
synchronized (monitor) {
if (list == null) {
list = new ArrayList<>();
list.add(...); // expensive operation
list.add(...); // expensive operation
list.add(...); // expensive operation
}
}

for (Foo foo : list) {
// do something with foo
}
}

最佳答案

它是线程安全的当且仅当这是您在结构上修改列表的唯一地方。

如果您在其他地方修改列表(例如使用 clear()),即使那个地方也使用了 synchronized,那么在迭代列表时可以很容易地修改列表

如果您打算在其他任何地方修改列表,则使用 Collections.unmodifiableList()确保(并记录)这一事实可能是个好主意。

关于java - 在同一个函数的 synchronized() block 中初始化后,能否在 synchronized() 之外安全地使用 Java 集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14857149/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com