以下代码是否被认为是线程安全的,即:写入列表是否保证发生在读取列表之前?我一直试图了解这在 Java 内存模型中是否被认为是安全的,但目前还不清楚。
通过基本的流程分析,看起来可以保证所有可能的线程在到达下面synchronized
的循环之前都必须通过初始化程序块for
,但是对该列表的迭代是否是确定性的和线程安全的?我不确定在使用下面的列表之前是否保证初始化。
假设这是类中唯一的方法。我知道在同步块内移动迭代可以保证线程安全,但我更想知道这个构造是否安全。
此外,假设列表永远不会逃脱类。
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
}
}