如果底层数据结构是 CopyOnWriteArrayList,修改操作线程在 List 上是否安全?

Is a modifying operation thread safe on a List if the underlying datastracture is CopyOnWriteArrayList?

我想让我的修改操作线程安全,同时还要遵守有关应用程序设计的最佳实践。

我假设有一个 Zoo class 来管理其中的动物,比如向动物园添加一个新的 Animal,删除一个等等,我想要这些操作是线程安全的。为简单起见,我在动物园中有一个 private List<Animal> animals 变量。我的第一个想法是在构造函数中将 animals 变量初始化为 CopyOnWriteArrayList 对象,每当创建一个新的 Zoo 对象时,就像这样:

private List<Animal> animals;

public Zoo() {
    this.animals = new CopyOnWriteArrayList<>();
}

public Zoo(List<Animal> animals) {
    this();
    addAnimals(animals);
}

public void addAnimals(Collection<Animal> animalsToAdd) {
    animals.addAll(animalsToAdd);
}

据我所知,CopyOnWriteArrayList 的方法是线程安全的,但是我可以通过这种方式实现线程安全吗,即:通过让底层数据结构成为 CopyOnWriteArrayList,同时保持参考变量作为 List?或者使 List<Animal> animals 变量和有问题的方法 synchronized 是更好的选择?

它是线程安全的。如果您使用 this.animals = ... 更改 this.animals 引用,您只需要考虑使 animals 易变 and/or 添加您自己的同步。如果您只是在构造函数中设置一次并且不再更改它,那么您就可以开始了。