【发布时间】:2017-09-01 21:38:28
【问题描述】:
假设我有以下代码:
public class MyClass
{
private volatile ArrayList<ArrayList<MyImmutableClass>> arraylist = new ArrayList<ArrayList<MyImmutableClass>>();
// ...code...
public void set(ArrayList<ArrayList<MyImmutableClass>> newArraylist)
{
arraylist = newArraylist;
}
public ArrayList<MyImmutableClass> get(int i)
{
return new ArrayList<MyImmutableClass>(arraylist.get(i));
}
}
我意识到,通过使arraylist 易失性,我实际上并没有使其内容也易失性——我只是使对ArrayList<ArrayList<MyImmutableClass>> 对象的引用易失性。但是我不能完全理解的一件事是,如果set() 在get() 构建其new ArrayList<MyImmutableClass> 的过程中更改arraylist 的引用会发生什么?
我的直觉说这很好——arraylist.get(i) 传递给 ArrayList 的复制构造函数的引用不会改变,只有arraylist 持有的引用会被set() 改变——但我没有改变能够以某种方式找到明确的答案。
【问题讨论】:
-
你害怕会发生什么?
-
你在这里所做的实际上是
CopyOnWriteArrayList背后的一般原则的一部分。 -
@Radiodef 怎么样?这里没有任何文字。
-
@shmosel 但是数组列表的易失性读取确保正确读取其内容如果对其内容的写入发生在易失性引用分配之前。 OP 的代码不是线程安全的,但这是
CopyOnWriteArrayList等数据结构背后的一般原则。 -
@Radiodef 为什么这段代码不是线程安全的?
标签: java multithreading arraylist